2010-02-26 5 views
5

Le code suivant fonctionne correctement pour Visual C++ 2008. Toutefois, lorsque vient à Visual C++ 6, j'obtiens l'erreur suivante. Puis-je savoir pourquoi, et comment je peux réparer l'erreur, mais toujours faire le destructeur reste en privé.Pourquoi Visual C++ 6 se plaint sur le destructeur privé

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): erreur C2248: 'X :: ~ X': ne peut pas accéder à un membre privé déclaré dans la classe 'X' C: \ Projects \ ttt6 \ main.cpp (175): voir la déclaration de « X :: ~ X »

+0

Les constructeurs/destructeurs ne devraient-ils pas toujours être publics? – vpram86

+3

@Avocator: Les constructeurs ne devraient pas toujours être publics. Exemples: Pour une classe abstraite, vous ne voulez que des classes dérivées appelant le constructeur (c'est comme cela que vous pouvez empêcher l'instanciation de la classe abstraite), donc vous le faites 'protected'. Pour les singletons, vous ne voulez que la méthode 'CreateInstance()' statique de la classe pour créer une instance, de sorte que le constructeur soit 'private'. –

+0

@Scott: Merci beaucoup. Je le comprends maintenant. – vpram86

Répondre

7

L'exemple révisé montre un bogue de compilateur confirmé pour VC6 - la solution de contournement commune consistait simplement à rendre le destructeur public.

+0

Avez-vous une référence pour ce bug est ce? –

+0

J'ai du mal à trouver de meilleures références alors ma mémoire ou de fils plus âgés comme http://www.codeguru.com/forum/archive/index.php/t-236067.html –

+1

Ce bogue a été également discuté un peu dans ce SO question: http://stackoverflow.com/questions/2130864/cannot-access-private-member-in-singleton-class-destructor –

4

Dans fun() vous créez un objet distinct, aa puis copie la valeur de la référence d'objet retourné par a::instance() à elle par l'opérateur d'affectation. Cela ne fonctionnera pas car le constructeur et le destructeur sont privés. aa devrait être une référence:

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

en fait, il essaie de le copier via la copie ctor. –

+0

Désolé. Certaines erreurs dans mon exemple de code. J'avais révisé. Le code donne toujours une erreur dans VC6 mais passe dans VC2008. –

+1

@Yan: Il ne passe pas, je le promets; votre test est faux. Donnez-nous votre code réel au lieu d'un exemple de code. – GManNickG

2

Quand est atteint la fin de plaisir(), votre variable ira hors de portée et la destructor sera appelée.

Il semble que vous essayez d'implémenter un singleton - peut-être que vous voulez dire ça?

a & aa = a :: instance();

Si aa est une référence plutôt qu'une instance, alors le destructeur ne sera pas appelé à la fin de fun().

+0

Désolé. Certaines erreurs dans mon exemple de code. J'avais révisé. Le code donne toujours une erreur dans VC6 mais passe dans VC2008. –

0

C'est juste un bug VC6. VC6 est très buggé. Vous pouvez utiliser std :: auto_ptr <> comme une solution de contournement.

#include <memory> 

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

Et, s'il vous plaît, déplacez l'implémentation de instance() dans le fichier cpp. Désolé, je ne me souviens pas du cas exact, mais il y a encore un autre bug VC6 avec l'implémentation singleton dans les fichiers d'en-tête. Nous avons eu quelques accidents il y a plusieurs années lors de l'utilisation de VC6. Le correctif consistait à déplacer l'implémentation d'instance() vers cpp.

Questions connexes