2008-09-22 104 views
7

在C++中创建类之前是否有声明类的对象?我问,因为我试图使用两个类,第一个需要在其中有第二个类的实例,但第二个类也包含第一个类的实例。我意识到你可能认为我可能陷入无限循环,但我实际上需要在第一课之前创建第二课的实例。甚至在创建该类之前声明一个对象

回答

37

你不能做这样的事情:

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类为向前声明允许您使用指针(和引用)的那类,但仍未有全班的定义。

5

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

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

class B 
{ 
public: 
    A *itemA; 
}; 

class A 
{ 
public: 
    B *itemB; 
}; 
+0

...或对其的引用:MyClass&rMyObject; – 2008-09-22 06:09:12

0

这是接近你想要的东西:第一类包含第二类,但第二类(即先创建)只有第一类的引用?

+0

我其实是想做相反的事情,第一类引用第二类,第二类包含第一类的实例。 – 2008-09-22 14:03:04

0

这被称为交叉引用。见here一个例子。

2

an elegant solution使用模板。

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已经完全宣告了 。这是 这种方法的神奇之处。

+0

有趣的(虽然它包含几个拼写错误)。但'getA'和'getB'确实是工厂:他们返回新的实例(按值)。 A的一个实例不具有-A也不具有B的实例具有-A。 – jwfearn 2008-09-23 00:50:11

相关问题