Klassendeklaration von eigebetteten Klassen
-
Hallo, ich habe eine Klasse mit einer eingebetteten Klasse:
//A.hpp class A { public: class B {}; };
Nun hab ich eine Klasse, die beide Klassen verwendet:
//Client.hpp //#ifndef und so ein Zeugs... class A; class A::B; class Client { private: A* a; B* b; }
Das Problem hier ist, dass ich keine 'reine' Deklaration von A::B durchführen kann, weil die Definition von A benötigt wird - ich müsste also vorher #include "A.hpp" schreiben, was ich aber nach dem Konzept von Scott Meyers im Buch Effektiv C++ programmieren, Lektion 34 (Kompilationsabhängigkeiten), nicht tun sollte.
Deshalb frage ich: Gibt es einen anderen Trick, eine Deklaration von B einzuführen ohne #include "A.hpp" zu benutzen? Ich könnte B natürlich auch aus A entfernen, aber von meinem Konzept her macht sich dir Klasse dort ganz gut.
Im Prinzip ist class A; doch eigentlich genau das Selbe wie class A::B;, oder?
-
Hi,
Ja das gibt es.
Das ist das so genannte pimpl-idiom.
Damit kannst du so ziemlich alles was in private steht verstecken.
Ein Beispiel:
// bsp.h #include <boost/shared_ptr.hpp> class Bsp { private: struct BspImpl; const boost::shared_ptr<BspImpl> pimpl; }; // bsp.cc #include "bsp.h" #include "a.hpp" struct Bsp::BspImpl { A *foo; A::B *bar; }; Bsp::Bsp() :pimpl(new Bsp::BspImpl) {}
[Edit]
Natürlich kannst du das auch ohne boost::shared_ptr machen, aber ich finde es besser, da man sich nicht um das löschen des Objekts kümmern muss.
[/Edit]Ich hoffe das Beispiel war verständlich genug, ansonsten kann ich dich nur Auf Exceptional C++ von Herb Sutter verweisen, da ist dieses PIMPL-IDIOM beschrieben.
MfG eViLiSSiMo
-
Der const boost::shared_ptr erlaubt aber das Kopieren, jedoch nicht das Zuweisen des Objekts... Wie wäre es mit boost::scoped_ptr? Dann muss man zwar noch einen leeren Destruktor in die .cpp schreiben, aber dafür hat man konsistente Semantiken und als theoretischen Bonus keinen Overhead.