两个类继承自相同的基础以互相看到

时间:2014-07-21 20:27:08

标签: c++ inheritance visibility

我有一个包含很多课程的程序。我希望程序中的类彼此可见。为此,我遵循一个技巧,使所有类都从一个基类继承,该基类保存指向每个类的指针。但是这样做我遇到了错误。下面是一段代码产生我之后的错误:

#include <iostream>
using namespace std;

class AClass;
class BClass;

class RoofClass {
 public:  
  RoofClass();
  AClass* a_class;
  BClass* b_class;
};

class BaseClass {
 public:  
  BaseClass(RoofClass* roof_class) {
   a_class = roof_class->a_class;
   b_class = roof_class->b_class;
  }
  AClass* a_class;
  BClass* b_class;  
};

class AClass : public BaseClass {
 public:  
  AClass(RoofClass* roof_class) : BaseClass(roof_class) {}
  void Afunction();
  int Aint = 1;
};

class BClass : public BaseClass {
 public:  
  BClass(RoofClass* roof_class) : BaseClass(roof_class) {}
  void Bfunction();
  int Bint = 2;
};

void AClass::Afunction() {
  cout << b_class->Bint << endl;
}

void BClass::Bfunction() {
  cout << a_class->Aint << endl;
}

RoofClass::RoofClass() {
  a_class = new AClass(this);
  b_class = new BClass(this);
}

int main(int argc, char **argv) {
  RoofClass roof_class;  
  cout << "b calls a" << endl;
  roof_class.b_class->Bfunction();
  cout << "a calls b" << endl;
  roof_class.a_class->Afunction();
}

Roof是顶级类,由A和B类组成。我希望A和B彼此可见。为实现这一点,正如我所说,它们都继承自Base类。特别是我的问题是,当B看到A时,A看不到B.其原因可能是由于A在Roof的构造函数中在B之前被初始化。那么,为什么我可以解决这个问题呢?

2 个答案:

答案 0 :(得分:1)

RoofClass构造函数创建AClass的实例时,它会将指针传递给自己,指向未初始化的成员a_classb_class。然后AClass构造函数复制这些值并返回。当RoofClass构造函数将a_class设置为指向新构造的对象时,AClass内的指针仍然指向任何内容。

您可能希望BaseClass存储指向RoofClass的指针:

class BaseClass {
 public:  
  BaseClass(RoofClass* roof_class) {
   r_class = roof_class;
  }
  RoofClass* r_class;
};
class AClass : public BaseClass {
 public:  
  AClass(RoofClass* roof_class) : BaseClass(roof_class) {}
  void Afunction();
  int Aint = 1;
  // access class B as r_class->b_class
};

答案 1 :(得分:0)

我实际上解决了这个问题。它是这样的: 在其构造函数中,RoofClass按顺序创建a和b对象。它首先通过进入其构造函数(实际上是继承的BaseClass的构造函数)并将a和b对象设置为roof a和b来初始化对象。但问题是,屋顶的b还没有建成。这就是为什么,a的b被初始化为00000000的值。当RoofClass转到b对象的构造函数进行初始化时,这次顶点a和b都到位,这样b的a和b的b被正确初始化。这就是为什么,b可以有一个合适的但不反过来。

解决方案是将InitPointer函数引入基类,该基类在屋顶对象构造所有a和b对象之后起作用。这样,InitPointer将a和b对象的指针设置为已构造的a和b对象。这是工作代码:

#include <iostream>

using namespace std;

class AClass;
class BClass;

class RoofClass {
 public:  
  RoofClass();
  AClass* a_class;
  BClass* b_class;
};

class BaseClass {
 public:  
  BaseClass() {}
  void InitPointer(RoofClass* roof_class) {
    a_class = roof_class->a_class;
    b_class = roof_class->b_class;
  }
  AClass* a_class;
  BClass* b_class;  
};

class AClass : public BaseClass {
 public:  
  AClass() : BaseClass() {}
  void Afunction();
  int Aint = 1;
};

class BClass : public BaseClass {
 public:  
  BClass() : BaseClass() {}
  void Bfunction();
  int Bint = 2;
};

void AClass::Afunction() {
  cout << b_class->Bint << endl;
}

void BClass::Bfunction() {
  cout << a_class->Aint << endl;
}

RoofClass::RoofClass() {
  a_class = new AClass();
  b_class = new BClass();
  a_class->InitPointer(this);
  b_class->InitPointer(this);
}

int main(int argc, char **argv) {
  RoofClass roof_class;  
  cout << "b calls a" << endl;
  roof_class.b_class->Bfunction();
  cout << "a calls b" << endl;
  roof_class.a_class->Afunction();
}

感谢所有讨论!