2010-02-26 11 views
5

Il seguente codice funziona correttamente per Visual C++ 2008. Tuttavia, quando arriva a Visual C++ 6, ottengo il seguente errore. Posso sapere perché, e come posso correggere l'errore, ma mantenere comunque il distruttore in privato.Perché Visual C++ 6 si lamenta sul distruttore privato

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): l'errore C2248: 'X :: ~ X': non può accedere membro privato dichiarato nella classe 'X' C: \ Projects \ ttt6 \ main.cpp (175): vedi dichiarazione di 'X :: ~ X'

+0

I costruttori/distruttori non dovrebbero essere sempre pubblici? – vpram86

+3

@Aviatore: i costruttori non dovrebbero essere sempre pubblici. Esempi: per una classe astratta, si desidera solo che le classi derivate chiamino il costruttore (è così che è possibile impedire l'istanziazione della classe astratta), in modo da renderlo 'protected'. Per i singleton si desidera solo il metodo statico 'CreateInstance()' per creare un'istanza, in modo da rendere il costruttore 'private'. –

+0

@Scott: Grazie mille. Lo capisco adesso. – vpram86

risposta

7

L'esempio rivisto mostra un bug del compilatore confermato per VC6: la soluzione alternativa era semplicemente rendere pubblico il distruttore.

+0

Avete qualche riferimento per ciò che questo bug è? –

+0

Ho difficoltà a trovare riferimenti migliori della mia memoria o thread precedenti come http://www.codeguru.com/forum/archive/index.php/t-236067.html –

+1

Questo bug è stato anche discusso un po 'in questo SO domanda: http://stackoverflow.com/questions/2130864/cannot-access-private-member-in-singleton-class-destructor –

4

In fun() si sta creando un oggetto separato, aa e quindi copiare il valore del riferimento oggetto restituito da a::instance() ad esso tramite l'operatore di assegnazione. Questo non funzionerà perché sia ​​il costruttore che il distruttore sono privati. aa dovrebbe essere un punto di riferimento:

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

effettivamente tenta di copiarlo tramite il copy ctor. –

+0

Siamo spiacenti. Qualche errore nel mio esempio di codice. Ho avuto una revisione. Il codice genera ancora errori in VC6 ma passa in VC2008. –

+1

@Yan: Non passa, lo prometto; il tuo test è sbagliato Dacci il tuo vero codice invece del codice di esempio. – GManNickG

2

Quando viene raggiunta la fine del divertimento(), la variabile sarà andare fuori del campo di applicazione e il distruttore saranno chiamati.

Sembra che tu stia cercando di implementare un singleton - forse vuoi dire questo?

a & aa = a :: instance();

Se aa è un riferimento anziché un'istanza, il distruttore non verrà chiamato alla fine di fun().

+0

Siamo spiacenti. Qualche errore nel mio esempio di codice. Ho avuto una revisione. Il codice genera ancora errori in VC6 ma passa in VC2008. –

0

È solo un bug VC6. VC6 è molto bacato. È possibile utilizzare std :: auto_ptr <> come soluzione alternativa.

#include <memory> 

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

E, per favore, spostare l'implementazione instance() nel file cpp. Spiacente, non ricordo caso esatto, ma c'è ancora un altro bug VC6 con implementazione singleton nei file header. Abbiamo avuto un paio di crash diversi anni fa quando ho usato VC6. La soluzione era spostare l'implmenetazione instance() su cpp.

Problemi correlati