我通常几乎没有想过,使用前进的声明,以便我不必包括标题.这个例子的一些东西
//----------------------- // foo.h //----------------------- class foo { foo(); ~foo(); }; //----------------------- // bar.h //----------------------- class foo; // forward declaration class bar { bar(); ~bar(); foo* foo_pointer; };
一些开发人员喜欢使用这种方法来避免包容圈的问题.我宁愿使用它来最大限度地减少广泛的包容层次结构的开销,这是物理设计的一个重要部分(特别是对于较大的项目).
然而,在某些情况下,我真的喜欢将成员声明为普通对象,而不是指针,以便从自动构建/销毁机制中受益.这导致了前向声明不能被使用的问题,因为在这种情况下编译器需要类定义,例如:
//----------------------- // foo.h //----------------------- class foo { foo(); ~foo(); }; //----------------------- // bar.h //----------------------- class foo; // Not enough given the way we declare "foo_object".. #include "foo.h" // ..instead this is required class bar { bar(); ~bar(); foo foo_object; };
所以,如果有人知道可以在这里使用的替代语言结构,我可以很高兴,以便我可以声明如foo_object,如示例所示,但不包括它的头.
问候
/罗伯特·
解决方法
只要使用一个智能指针 – 你甚至可以在这种情况下使用auto_ptr.
//----------------------- // bar.h //----------------------- #include <memory> class foo; // Not enough given the way we declare "foo_object".. class bar { public: bar(); ~bar(); foo &foo_object() { return *foo_ptr; } const foo &foo_object() const { return *foo_ptr; } private: auto_ptr<foo> foo_ptr; };
您可以获得自动内存管理的所有好处,而无需在bar.h中了解foo的任何内容.关于Herb Sutter的建议,请参阅Wrapping Pointer Data Members.
如果您真的希望自动执行默认构造,请尝试:
#include <iostream> using namespace std; class Foo; template <typename T> class DefaultConstuctorPtr { T *ptr; void operator =(const DefaultConstuctorPtr &); DefaultConstuctorPtr(const DefaultConstuctorPtr &); public: DefaultConstuctorPtr() : ptr(new T()) {} ~DefaultConstuctorPtr() { delete ptr; } T *operator *() { return ptr; } const T *operator *() const { return ptr; } }; class Bar { DefaultConstuctorPtr<Foo> foo_ptr; public: Bar() {} // The compiler should really need Foo() to be defined here? }; class Foo { public: Foo () { cout << "Constructing foo"; } }; int main() { Bar bar; }