2010-02-26 16 views
5

Poniższy kod działa poprawnie w przypadku programu Visual C++ 2008. Jednak w przypadku programu Visual C++ 6 pojawia się następujący błąd. Mogę wiedzieć, dlaczego i jak mogę naprawić błąd, ale nadal sprawi, że destruktor pozostanie w prywatnym.Dlaczego program Visual C++ 6 narzeka na prywatny destruktor

class X 
{ 
public: 
    static X& instance() 
    { 
     static X database; 
     return database; 
    } 

private: 

    X() {}     // Private constructor 
    ~X() {}     // Private destructor 
    X(const X&);    // Prevent copy-construction 
    X& operator=(const X&); // Prevent assignment 
}; 

int main() 
{ 
    X::instance(); 
} 

C: \ Projects \ ttt6 \ main.cpp (178): error C2248: 'X :: ~ X': nie ma dostępu do prywatnych członka zadeklarowana w klasie 'X' C: \ Projects \ ttt6 \ main.cpp (175): patrz deklaracja „X :: ~ X”

+0

Czy konstruktory/destruktory nie powinny być zawsze publiczne? – vpram86

+3

@Aviator: Konstruktorzy nie zawsze powinni być publiczni. Przykłady: W przypadku klasy abstrakcyjnej potrzebujesz tylko klas pochodnych wywołujących konstruktor (w ten sposób można zapobiec tworzeniu wystąpienia klasy abstrakcyjnej), więc staje się ona "chroniona". W przypadku singletonów, do utworzenia instancji wymagana jest tylko statyczna metoda 'CreateInstance()' klasy, więc konstruktor staje się "prywatny". –

+0

@Scott: Wielkie dzięki. Rozumiem to teraz. – vpram86

Odpowiedz

7

Zmieniona próbka pokazuje potwierdzony błąd kompilatora dla VC6 - wspólnym rozwiązaniem było po prostu udostępnienie destruktora jako publicznego.

+0

Czy masz jakieś odniesienia do tego, co to jest błąd? –

+0

Trudno jest znaleźć lepsze referencje niż moja pamięć lub starsze wątki, takie jak http://www.codeguru.com/forum/archive/index.php/t-236067.html –

+1

Ten błąd został również omówiony nieco w tym SO pytanie: http://stackoverflow.com/questions/2130864/cannot-access-private-member-in-singleton-class-destructor –

4

W fun() tworzysz osobny przedmiot, aa a następnie kopiując wartość odniesienia obiekt zwrócony przez a::instance() do niego za pośrednictwem operatora przypisania. To nie zadziała, ponieważ zarówno konstruktor, jak i destruktor są prywatne. aa powinno być odniesienie:

a &aa = a::instance(); 
+0

faktycznie próbuje go skopiować za pomocą ctor kopii. –

+0

Przepraszamy. Jakiś błąd w moim przykładzie kodu. Zrewidowałem. Kod nadal podaje błąd w VC6, ale przechodzi w VC2008. –

+1

@Yan: Nie przechodzi, obiecuję; twój test jest błędny. Podaj nam swój prawdziwy kod zamiast przykładowego kodu. – GManNickG

2

Kiedy koniec zabawy() zostanie osiągnięty, zmienna będzie wychodzić z zakresem i destruktor zostanie wywołana.

Wygląda na to, że próbujesz zaimplementować singleton - może masz na myśli?

a & aa = a :: instance();

Jeśli aa jest referencją, a nie instancją, destruktor nie zostanie wywołany na końcu zabawy().

+0

Przepraszam. Jakiś błąd w moim przykładzie kodu. Zrewidowałem. Kod nadal podaje błąd w VC6, ale przechodzi w VC2008. –

0

To jest po prostu błąd VC6. VC6 jest bardzo błędny. Możesz użyć std :: auto_ptr <> jako obejścia.

#include <memory> 

class X 
{ 
    friend std::auto_ptr<X>; 
public: 
    static X& instance() 
    { 
     static std::auto_ptr<X> database(new X); 
     return *database; 
    } 
..... 
}; 

I, proszę, przenieś implementację instance() do pliku cpp. Niestety, nie pamiętam dokładnego przypadku, ale jest jeszcze jeden błąd VC6 z implementacją singleton w plikach nagłówkowych. Kilka lat temu mieliśmy kilka awarii, kiedy używaliśmy VC6. Poprawka polegała na przeniesieniu implonetation instance() do cpp.

Powiązane problemy