2009-06-20 16 views
120

Mögliche Duplizieren:
Forward declaration of nested types/classes in C++Wie kann ich eine innere Klasse weiterleiten?

Ich habe eine Klasse wie so ...

class Container { 
public: 
    class Iterator { 
     ... 
    }; 

    ... 
}; 

An anderer Stelle habe ich einen Container :: Iterator durch Verweis übergeben möchten, aber ich möchte die Header-Datei nicht einschließen. Wenn ich versuche, die Klasse zu deklarieren, bekomme ich Kompilierungsfehler.

class Container::Iterator; 

class Foo { 
    void Read(Container::Iterator& it); 
}; 

Kompilieren der obige Code gibt ...

test.h:3: error: ‘Iterator’ in class ‘Container’ does not name a type 
test.h:5: error: variable or field ‘Foo’ declared void 
test.h:5: error: incomplete type ‘Container’ used in nested name specifier 
test.h:5: error: ‘it’ was not declared in this scope 

Wie kann ich uns darauf, diese Klasse deklarieren also muss ich die Header-Datei nicht enthalten, die die Iterator-Klasse deklariert?

Antwort

102

Dies ist einfach nicht möglich. Sie können keine verschachtelte Struktur außerhalb des Containers weiterleiten. Sie können es nur innerhalb des Containers weiterleiten.

Sie werden eine der folgenden

  • tun müssen Machen Sie die Klasse nicht-verschachtelten
  • Ihre Erklärung Reihenfolge ändern, so dass die verschachtelte Klasse vollständig zuerst definiert ist
  • eine gemeinsame Basisklasse erstellen Dies kann sowohl in der Funktion verwendet als auch von der geschachtelten Klasse implementiert werden.
+2

Die gemeinsame Basisklasse ist die am meisten genutzte Lösung. – Coyote

+0

Sie können Freund verwenden, um dies zu umgehen, wenn Sie möchten. –

+1

Das ist falsch: http: //en.cppreference.com/w/cpp/language/nested_types – Nikerboker

18

Ich glaube nicht vorwärts innere Klasse auf einer unvollständigen Klasse Werke erklären (denn ohne die Klassendefinition, gibt es keine Möglichkeit zu wissen, ob es tatsächlich eine innere Klasse ist). So haben Sie die Definition von Containern, mit einer vorderen erklärte innere Klasse umfassen müssen:

class Container { 
public: 
    class Iterator; 
}; 

dann in einem separaten Header, implementieren Container :: Iterator:

class Container::Iterator { 
}; 

Dann #include nur die Container-Header (oder nicht über vorwärts Sorge zu erklären und sind nur beide)

+4

Gute Antwort, außer dem Teil in der ersten Paragraf-Klammer. Das "es gibt keine Möglichkeit zu wissen, ob es tatsächlich eine innere Klasse gibt" macht in diesem Zusammenhang keinen Sinn und ist zweifelhaft, um genau zu sein. Der springende Punkt einer Forward-Deklaration ist, dass Sie dem Compiler sagen, dass es eine Klasse (oder in diesem Fall eine innere Klasse) gibt. Diese spezifische Aussage von dir wäre genauso für normale Klassen und würde bedeuten, dass du nichts weiterleiten kannst. – Aaron

1

ich keine Möglichkeit, genau wissen, zu tun, was Sie wollen, aber hier ist eine Abhilfe, wenn Sie bereit sind, Vorlagen zu verwenden:

// Foo.h 
struct Foo 
{ 
    export template<class T> void Read(T it); 
}; 

// Foo.cpp 
#include "Foo.h" 
#include "Container.h" 
/* 
struct Container 
{ 
    struct Inner { }; 
}; 
*/ 
export template<> 
    void Foo::Read<Container::Inner>(Container::Inner& it) 
{ 

} 

#include "Foo.h" 
int main() 
{ 
    Foo f; 
    Container::Inner i; 
    f.Read(i); // ok 
    f.Read(3); // error 
} 

Hoffentlich könnte dieses Idiom einige Sie nützlich sein (und hoffentlich Ihr Compiler ist EDG-basierte und implementiert Export;)).

Verwandte Themen