10

无论如何,在用 C++ 创建类之前声明一个类的对象吗?我问是因为我正在尝试使用两个类,第一个类需要在其中包含第二个类的实例,但第二个类也包含第一个类的实例。我意识到您可能认为我可能会陷入无限循环,但实际上我需要在第一个类之前创建第二个类的实例。

4

5 回答 5

42

你不能做这样的事情:

class A {
    B b;
};
class B {
    A a;
};

最明显的问题是编译器不知道生成类 A 需要多大,因为 B 的大小取决于 A 的大小!

但是,您可以这样做:

class B; // this is a "forward declaration"
class A {
    B *b;
};
class B {
    A a;
};

将类 B 声明为前向声明允许您使用指向该类的指针(和引用),而无需完整的类定义。

于 2008-09-22T06:08:41.930 回答
5

你不能声明一个未定义类的实例,但你可以声明一个指针

class A;  // Declare that we have a class A without defining it yet.

class B
{
public:
    A *itemA;
};

class A
{
public:
    B *itemB;
};
于 2008-09-22T06:07:05.070 回答
2

有一个使用模板的优雅解决方案。

template< int T > class BaseTemplate {};
typedef BaseTemplate< 0 > A;
typedef BaseTemplate< 1 > B;
// A
template<> class BaseTemplate< 0 >
{
public:
   BaseTemplate() {} // A constructor
   B getB();
}

// B
template<> class BaseTemplate< 1 >
{
public:
   BaseTemplate() {} // B constructor
   A getA();
}

inline B A::getB() { return A(); }
inline A B::getA() { return B(); }

此代码将起作用!那么,为什么它会起作用?原因与模板的编译方式有关。模板会延迟函数签名的创建,直到您在某处实际使用该模板。这意味着 getA() 和 getB() 都不会分析它们的签名,直到类 A 和 B 都已经完全声明之后。这就是这种方法的魔力。

于 2008-09-22T16:04:23.653 回答
0

这是否接近您想要的:第一个类包含第二个类,但第二个类(即首先创建)仅具有对第一个类的引用?

于 2008-09-22T06:08:34.117 回答
0

这称为交叉引用。请参阅此处的示例。

于 2008-09-22T06:11:04.547 回答