sha*_*kin 10 c++ physical-design forward-declaration
我通常几乎不再思考,使用前向声明,这样我就不必包含标题.这个例子的东西:
//-----------------------
// foo.h
//-----------------------
class foo
{
foo();
~foo();
};
//-----------------------
// bar.h
//-----------------------
class foo; // forward declaration
class bar
{
bar();
~bar();
foo* foo_pointer;
};
Run Code Online (Sandbox Code Playgroud)
一些开发人员喜欢使用此方法来避免包含圈子的问题.我宁愿用它来减少广泛的包含层次结构的开销,这是物理设计的一个重要部分(特别是对于大型项目).
但是,在某些情况下,我真的想将成员声明为普通对象而不是指针,以便从自动构建/销毁机制中受益.这导致了前向声明不能再使用的问题,因为在这种情况下编译器需要类定义,例如:
//-----------------------
// 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;
};
Run Code Online (Sandbox Code Playgroud)
所以,如果有人知道可以在这里使用的替代语言构造,我会很高兴我可以声明"foo_object",如示例中所示,但不包括其标题.
问候
/罗伯特·
Pie*_*ter 12
你不能.在声明类时,编译器需要知道对象的大小.
引用是一种替代方法,尽管它们必须在构造时实例化,因此并不总是可行的.
另一种选择是智能指针,但我认为技术上仍然是一个指针.
很高兴知道为什么你不想使用指针建议其他构造虽然......
你想要什么不能在C++中完成.为了生成对象的代码,您的编译器需要知道它的类需要多少存储空间.为了解这一点,它必须知道每个类成员需要多少存储空间.
如果要创建一个类型为bar的类型为bar的类型,编译器必须知道foo有多大.它知道的唯一方法是它是否有可用的foo定义(通过#include).否则,您唯一的选择是使用foo的前向声明和指针或引用而不是实际的foo对象.
只需使用智能指针 - 在这种情况下甚至可以使用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;
};
Run Code Online (Sandbox Code Playgroud)
您可以获得自动内存管理的所有好处,而无需在bar.h中了解有关foo的任何信息.请参阅为Herb Sutter建议包装指针数据成员.
如果您确实希望默认构造自动发生,请尝试以下方法:
#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;
}
Run Code Online (Sandbox Code Playgroud)