Błąd linkera - nie moze znalezc zmiennej statycznej. czemu?

0

Hej. Mam problem z następującym kodem - występuje błąd linkera (undefined reference to p_). Dlaczego? i co zrobić, żeby program poszedł?

(Jest to bardzo prosty program testujący niewspółbieżny Singleton)

#include <iostream>

class SingleClass
{
	public:
		static SingleClass* getInstance() {
			if (p_) return p_;
			return new SingleClass();	
		}
		int getFoo() const {
			return foo_;
		}
		void setFoo (int value) {
			foo_ = value;
		}
	private:	
		static SingleClass * p_;
		int foo_;
		SingleClass() {
			foo_ = 1;
		}
		~SingleClass() {
			if (p_) delete p_;
		}
};

int main(int argc, char *argv[])
{
	std::cout << SingleClass::getInstance()->getFoo();
}

0

bo zapomniales ZDEFINIOWAC w ktorym module .cpp ma zostac FIZYCZNIE*) umieszczona statyczna zmienna SingleClass::p_.. Formalnie, zarzut brzmi: "brak inicjalizacji statycznego pola klasy". innymi slowy, Twoj kod powinien wygaldac mwiecej tak:

#include <iostream>

class SingleClass
{
        public:
                static SingleClass* getInstance() {
                        if (p_) return p_;
                        return new SingleClass();        
                }
                int getFoo() const {
                        return foo_;
                }
                void setFoo (int value) {
                        foo_ = value;
                }
        private:        
                static SingleClass * p_;
                int foo_;
                SingleClass() {
                        foo_ = 1;
                }
                ~SingleClass() {
                        if (p_) delete p_;
                }
};

SingleClass* SingleClass::p_ = 0;  // <--TEGO Ci brak. umiesc w ktorymkolwiek .cpp ktory zna tresc klasy SingleClass
// btw. =0 nie jest konieczne. mozesz pominac, ale lepiej zostawic:)

int main(int argc, char *argv[])
{
        std::cout << SingleClass::getInstance()->getFoo();
}

sęk tkwi w tym, że każda zmienna musi mieć jakąś lokalizację.. to, że napiszesz static-blah w klasie, nie oznacza, ze zostanie ona natychmiast tu i teraz utworzona!*) to tylko forward-deklaracja ze taka zmienna statyczna bedzie istniala.. to tak jakbys napisal globalne extern int blah; i zapomnial gdziesindziej uczynic globalnego int blah=5; [pozbawionego 'static' ktore by go 'uprywatnilo']

*) jesli by tak bylo, ze automatycznie sie by ona tworzyla w miejscu deklaracji, wyobraz sobie te bledy linkera, gdybys tresc klasy majacej static field trzymal w pliku .hpp i w 5ciu plikach .cpp #include ów .hpp. Efekt: byłoby 5ciokrotne utworzenie zmiennej i w linkerze kolizja pieciu identycznych symboli. i dlatego trzeba je recznie fizycznie umiejscowic w jednym pliku .cpp. i nieszkodzi, ze masz u siebie tylko jeden modul .cpp i nie masz plikow .hpp. C++ jest przygotowany do pracy z projektami porozszczepianymi na wiele plikow i wiele roznych konstrukcji i przymusow wynika wlasnie z tego ze zaklada sie ze masz wiele plikow z kodem.

0

Jasne, że tak :) Taki ja stary a taki głupi :-)
Dzięki :-)

0

Przyjrzyj się jeszcze raz funkcji getInstance(), bo jest tam coś złego.

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