在创建该类之前声明一个对象

时间:2020-03-06 14:31:32  来源:igfitidea点击:

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

解决方案

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

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

class B
{
public:
    A *itemA;
};

class A
{
public:
    B *itemB;
};

这是否接近我们想要的内容:第一类包含第二类,但是第二类(将首先创建)仅引用第一类?

我们不能执行以下操作:

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声明为前向声明,使我们可以使用指向该类的指针(和引用),而无需整个类的定义。

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

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

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(); }

  
  This code will work! So, why does it
  work? The reason has to do with how
  templates are compiled. Templates
  delay the creation of function
  signatures until you actually use the
  template somewhere. This means that
  neither getA() nor getB() will have
  their signatures analyzed until after
  both classes A and B have already been
  fully declared. That's the magic of
  this method.