Frage

Ich habe eine Klasse wie folgt aus:

class Inner;

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

in der CPP, erstellt der Konstruktor eine Instanz von Inner mit new und dem destructor deletes es. Das ist ziemlich gut funktioniert.
Jetzt möchte ich diesen Code zu verwenden auto_ptr ändern, damit ich schreiben:

class Inner;

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

Nun wird der Konstruktor initialisiert die auto_ptr und der destructor tut nichts.

Aber es funktioniert nicht. Das Problem scheint entstehen, wenn ich diese Klasse bin instanziieren. Ich erhalte diese Warnung:

  

Warnung C4150: Löschen von Zeigern auf   unvollständiger Typ ‚Inner‘; Nein   destructor genannt

Nun, das ist natürlich sehr schlecht, und ich verstehe, warum es passiert, der Compiler nicht über das d'tor von Inner nicht wissen, wann die Vorlage von auto_ptr<Inner> instanziieren

Also meine Frage: Gibt es eine Möglichkeit zur Verwendung auto_ptr mit einer Vorwärts-Erklärung, wie ich in der Version tat, dass Anwendungen einfach nur Zeiger
? jede Klasse erkläre ich einen Zeiger auf ein riesiger Aufwand und manchmal einfach unmöglich zu #include haben. Wie wird dieses Problem in der Regel behandelt?

War es hilfreich?

Lösung

Sie müssen die Header definieren class Inner in die Datei aufgenommen werden, wo Cont::~Cont() Umsetzung befindet. So können Sie immer noch eine Vorwärtsdeklaration in Teh-Header definieren class Cont haben und den Compiler sieht class Inner Definition und können die Destruktoraufrufs.

//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()
{
}

Andere Tipps

Es stellt sich heraus das Problem tritt nur auf, wenn ich den c'tor inline machen. Wenn ich den c'tor in der CPP setzen, nach der Angabe von oks Inner allem.

Sie können boost :: shared_ptr () statt betrachten. Es hat keine praktischen Nachteile statt der Leistung und ist viel freundliche Erklärungen zu übermitteln:

boost::shared_ptr<class NeverHeardNameBefore> ptr;

ist in Ordnung, ohne zusätzliche Erklärungen über.

Shared_ptr tut mehr als auto_ptr, wie Referenzzählung, aber es sollte nicht schaden, wenn Sie es nicht brauchen.

Es scheint lächerlich, aber ich löste das gleiche Problem, das von #include <memory> zur Cont.h Datei hinzufügen.

Die Forward-Deklaration im Header ist in Ordnung, wenn Sie den destructor in der cont.cpp Datei implementieren und Sie sind inner.h, wie andere hingewiesen.

Das Problem bei der Verwendung von Cont sein könnte. In jedem CPP, dass Anwendungen (und zerstört) Cont Sie müssen umfassen cont.h UND inner.h. Das löste das Problem in meinem Fall.

Diese Frage (Löschen Objekt mit eigenem destructor) und this Frage (wie IsComplete Vorlage schreiben) können Ihnen helfen werden.

Sie sind nicht technisch soll Standardbibliothek Vorlagen mit unvollständigen Typen instanziiert, obwohl ich keine Implementierung wissen, wo dies nicht funktionieren wird. In der Praxis ist Sharptooth Antwort, was würde ich empfehlen, auch.

Es war wirklich nichts falsch mit einem nackten Zeiger für Ihren impl Zeiger verwenden, solange man auf sie in Ihrem destructor löscht nennen. Sie sollten wahrscheinlich auch den Kopierkonstruktor und Zuweisungsoperator implementieren oder deaktivieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top