Question

J'ai une classe comme ceci:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    Inner* m_inner;
};

dans le Cpp, le constructeur crée une instance de Inner avec new et les destructor deletes il. Cela fonctionne assez bien.
Maintenant, je veux changer ce code pour utiliser auto_ptr donc j'écris:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    std::auto_ptr<Inner> m_inner;
};

Maintenant, le constructeur a initialisé le auto_ptr et l'destructor ne fait rien.

Mais cela ne fonctionne pas. le problème semble se poser quand j'instancier cette classe. Je reçois cet avertissement:

  

C4150 d'avertissement: suppression du pointeur   type incomplet « intérieure »; non   destructor appelé

Eh bien, ce qui est évidemment très mauvais et je comprends pourquoi il arrive, le compilateur ne connaît pas le d'tor de Inner lors de l'instanciation du modèle de auto_ptr<Inner>

Ma question: Y at-il un moyen d'utiliser auto_ptr une déclaration en avant comme je l'ai fait dans la version qui utilise des pointeurs tout simplement
? Ayant à #include chaque classe, je déclare un pointeur est un énorme problème et parfois, tout simplement impossible. Comment est-ce problème généralement géré?

Était-ce utile?

La solution

Vous devez inclure l'en-tête définissant class Inner dans le fichier où la mise en œuvre de Cont::~Cont() est situé. De cette façon, vous avez encore une déclaration avant dans Teh tête définissant class Cont et le compilateur voit définition class Inner et peut appeler le destructor.

//Cont.h
class Inner; // is defined in Inner.h
class Cont 
{ 
    virtual ~Cont(); 
    std::auto_ptr<Inner> m_inner;
};

// Cont.cpp
#include <Cont.h>
#include <Inner.h>

Cont::~Cont()
{
}

Autres conseils

Il s'avère que le problème ne se produit que lorsque je fais la ligne de c'tor. Si je mets le c'tor dans le cpp, après la decleration de tout Inner va bien.

Vous pouvez envisager de boost :: shared_ptr () à la place. Il n'a pas d'inconvénients pratiques au lieu de la performance, et est beaucoup plus facile de transmettre des déclarations:

boost::shared_ptr<class NeverHeardNameBefore> ptr;

est correct, sans déclarations supplémentaires ci-dessus.

shared_ptr fait plus que auto_ptr, comme le comptage de référence, mais il ne doit pas faire du mal si vous ne avez pas besoin.

Il semble ridicule mais je résolu le même problème en ajoutant #include <memory> au fichier Cont.h.

La déclaration en avant dans l'en-tête est ok si vous implémentez le destructor dans le fichier cont.cpp et que vous incluez inner.h, comme d'autres ont souligné.

Le problème pourrait être l'utilisation de Cont. Dans chaque cpp qui utilise (et détruit) Cont vous devez inclure cont.h ET inner.h. Cela a résolu le problème dans mon cas.

Cette question (objet suppression avec destructor privé) et this question (comment écrire modèle IsComplete) peut vous aider.

Vous n'êtes pas techniquement censé instancier des modèles de bibliothèque standard avec des types incomplets, bien que je ne connais pas la mise en œuvre où cela ne fonctionnera pas. Dans la pratique, la réponse de Sharptooth est ce que je vous recommande également.

Il n'y avait vraiment rien de mal à l'aide d'un pointeur nu pour votre pointeur impl, aussi longtemps que vous appelez supprimer sur dans votre destructor. Vous devez implémenter probablement ou désactiver le constructeur de copie et d'affectation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top