Singleton undefined reference

0

Częśc. Czy mógłby ktoś sprawdzić ten kawałek kodu? Niestety nie mogę znależć rozwiązania a porównując z tymi co znalazłem w necie wydaje się że powinno być dobrze
Błąd to:
undefined reference to `JsonFonts::instance' JsonFonts.h line 32

/*
 * JsonFonts.h
 *
 *  Created on: 16 lut 2021
 *      Author: danie
 */
#include <vector>
#include <cardSD.h>
#include <ArduinoJson-v6.15.2.h>

#ifndef SRC_FILEMANAGER_JSONFONTS_H_
#define SRC_FILEMANAGER_JSONFONTS_H_

class JsonFonts {
private:
	JsonFonts();
	virtual ~JsonFonts();
	static JsonFonts* instance;
	struct FontsSettings{
		std::string font;
		uint8_t height;
		uint8_t width;
		string path;
	};
	FontsSettings actualSettings;
	vector<FontsSettings> fontsSettings;
public:
	static JsonFonts* getInstance(){
		if(instance == nullptr)
			instance = new JsonFonts();
		return instance;
	}
	void findFontToCreate(uint8_t width, uint8_t height);
	string getPath(uint8_t width, uint8_t height);
	uint8_t getWidth(uint8_t width, uint8_t height);
	uint8_t getHeight(uint8_t width, uint8_t height);
};

#endif /* SRC_FILEMANAGER_JSONFONTS_H_ */

2

Za mocno zakręciłeś.

class JsonFonts
{
	private:
    JsonFonts();
	public:
    virtual ~JsonFonts();
    static JsonFonts &instance()
	{
		static JsonFonts jf;
        return jf;
    }
};
2

Nie jest to pełnoprawny Singelton, domyślny konstruktor kopiujący i operator przypisania pozwala na jego kopiowanie.
Zamień na:

#include <iostream>

using namespace std;

class JsonFonts {
private:
    JsonFonts() = default;
public:
    JsonFonts(JsonFonts const&) = delete;
    void operator=(JsonFonts const&) = delete;
    virtual ~JsonFonts(){};

    static JsonFonts& getInstance(){
        static JsonFonts instance;
        return instance;
    }
    int i {10};
};

int main()
{
  auto& ref1 {JsonFonts::getInstance()};
  auto& ref2 {JsonFonts::getInstance()};
  ref1.i = 50;
  cout << ref2.i << endl;
}
0

W sumie to ja wole jeszcze prostsze podejście:

#include <iostream>
using namespace std;

class JsonFontsSingleton
{
	private:
	struct JsonFonts
	{
		void call() { cout<<"call"<<endl; }
		void *check() { return this; }
	};
	public:
	JsonFonts *operator->()
	{
		static JsonFonts jf;
		return &jf;
	}
};

int main()
{
	JsonFontsSingleton()->call();
	if(JsonFontsSingleton()->check()==JsonFontsSingleton()->check()) cout<<"same object"<<endl;
	return 0;
}
0

Dzięki wszystkim za przedstawienie różnych opcji. Po pracy dokładnie się im przyjrzę i mam nadzieję, że wszystko zrozumiem :D

4

Offtopic: Nazwa JsonFonts jest strasznie dziwna, bo Json jest związany z komunikacją sieciową, a Fonts z interface użytkownika. Coś jak "wiosło na pustyni".

2

Sercem problemu jest, że koledze nie wychodzi linkowanie do statycznej składowej klasy, wcześniej czy później będzie musiał się nauczyć.

@danielbr3

Brakuje ci nie w headerze, a w źródle CPP (tylko w jednym, najlepiej stosownym dla klasy JsonFonts.cpp)

JsonFonts::JsonFonts* instance;

Zgadzam się z @MarekR22 - fatalna nazwa. Niestety z Arduino wychodzą w znacznym procencie koszmarki architektonicze

0

Mam jeszcze jedno pytanie. Sprawdziłem co zostało zastosowane w drugim przedstawionym rozwiązaniu i je napisałem. Chciałbym tylko jeszcze użyć metody ładującej plik Json w konstruktorze i niestety w żaden sposób nie udaje mi się tego zrobić w tym konstruktorze zdefiniowanym jako domyślny. Jest w ogóle taka możliwość?

0
danielbr3 napisał(a):

Mam jeszcze jedno pytanie. Sprawdziłem co zostało zastosowane w drugim przedstawionym rozwiązaniu i je napisałem. Chciałbym tylko jeszcze użyć metody ładującej plik Json w konstruktorze i niestety w żaden sposób nie udaje mi się tego zrobić w tym konstruktorze zdefiniowanym jako domyślny. Jest w ogóle taka możliwość?

Domyślny to domyślny deklarowany automaigcznie.
Chcesz sam napisać treść to zabierz słówko default

Weź użyj wersję uproszczoną, masz zwykła strukturę ale ze wszelkimi zabezpieczeniami.

0

@_13th_Dragon: Poczytałem wcześniej o tych domyślnych konstruktorach kopiujących i znalazłem że to default musi się znaleźć przy jakimś konstruktorze, żeby delete przy pozostałych pełniło swoją funkcję. Za chwile sprawdzę tą trzecią wersje ze strukturą

0

Dzięki wszystkim za pomoc. Całość działa tak jak powinna

1 użytkowników online, w tym zalogowanych: 0, gości: 1