Singleton undefined reference

Singleton undefined reference
D3
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Postów:58
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

Kopiuj
/*
 * 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_ */

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:6 dni
2

Za mocno zakręciłeś.

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

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
B4mbus
Tu będzie vexing parse.
_13th_Dragon
Racja, poprawiam.
D3
Mógłbys troche wyjasnić jak to konkretne rozwiązanie działa? Jak rozumiem do dowolnej funkcji mogę się teraz odwołać w taki sposób? JsonFonts::instance().function(); Czy takie rozwiązanie jest już optymalne i nie będzie próbowało przy każdym wywołaniu funkcji tworzyć na nowo obiektu? W konstruktorze mam dość długą funkcję jak na moc obliczeniową mikrokontrolera i zależy mi na tym, żeby był on wywoływany.
_13th_Dragon
Daj komunikat w konstruktorze i sprawdź, przecież zmienna 'jf' jest statyczna
TomaszLiMoon
Obiekt statyczny wewnątrz funkcji jf jest inicjalizowany (wywołany zostanie konstruktor) dopiero wtedy, kiedy sterowanie po raz pierwszy zostanie przekazane do funkcji instance. Następne jej wywołania nie będą już inicjalizowały/tworzyły tego obiektu.
TomaszLiMoon
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 2 godziny
  • Postów:530
2

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

Kopiuj
#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;
}
Zobacz pozostały 1 komentarz
_13th_Dragon
To jest to samo (koniecznie trzeba dodać to co w tym poście napisano), no i przy okazji dowód (nie do końca przekonywujący, ale jakiś) że masz ten sam obiekt.
D3
Ok. czyli to jest bezpieczniejsze zastosowanie singletona a to co napisałeś to bardziej uproszczona wersja ale działająca tak samo?
TomaszLiMoon
Nie, poprzednia wersja nie jest uproszczoną wersją singeltona, gdyż pozwala na kopiowanie obiektów - zobacz https://godbolt.org/z/M8b533
_13th_Dragon
Nie, zwyczajnie (nie wiedzieć czemu) uznałem to za tak oczywiste że nie wymaga tłumaczeń.
D3
Jasne, ja niestety nie umiem ąz tak dobrze C++ bo na mikrokontrolerach w wiekszości przypadków wystarczają najprostsze elementy :D
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:6 dni
0

W sumie to ja wole jeszcze prostsze podejście:

Kopiuj
#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;
}

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon
D3
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Postów:58
0

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

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:2 minuty
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".


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
_13th_Dragon
Z tym że wiosło na pustyni ma szansę się przydać :D
AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
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)

Kopiuj
JsonFonts::JsonFonts* instance;

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


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 2x, ostatnio: AnyKtokolwiek
Zobacz pozostałe 3 komentarze
_13th_Dragon
"... nauczą się deptać w brązowym, to ... " ... to normalny chodnik dla nich, to coś dziwacznego i niebezpiecznego.
AK
@danielbr3: to jest jakość "bibliotek" arduino - większość autorów nawet nie wie, co znaczy to słwoo. Kompletem powinien być moduł żródłowy
D3
aż tak źle jest z nimi? :D W sumie to jedyny raz gdy z jakiejkolwiek z Arduino korzystam i nawet się jej jakoś szczególnie nie przyglądałem
AK
@danielbr3: Np zmora: konflikty podobnych bibliotek (np na ten sam chip, albo jak z dowolnych innych powodów identyfikator się pokrywa). Lekarstwo leży na ulicy, tylko je podnieść: C++ namespace. Ale nie, w tym kręgu to jest poza zasięgiem intelektualnym
_13th_Dragon
... bariera nie do przebicia :D "aż tak źle jest z nimi?" - A nawet gorzej!
D3
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Postów:58
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ść?

edytowany 1x, ostatnio: danielbr3
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:6 dni
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.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
D3
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Postów:58
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ą

_13th_Dragon
Nie, wcale nie mus. default to komenda kompilatorowi: - sam sobie napisz.
D3
Ok. To musiałem źle zinterpretować to co czytałem. W takim razie nie powinno być problemu ale jeszcze przetestuję ze strukturą :D
D3
  • Rejestracja:ponad 6 lat
  • Ostatnio:7 dni
  • Postów:58
0

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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.