我有一个包含很多课程的程序。我希望程序中的类彼此可见。为此,我遵循一个技巧,使所有类都从一个基类继承,该基类保存指向每个类的指针。但是这样做我遇到了错误。下面是一段代码产生我之后的错误:
#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之前被初始化。那么,为什么我可以解决这个问题呢?
答案 0 :(得分:1)
当RoofClass
构造函数创建AClass
的实例时,它会将指针传递给自己,指向未初始化的成员a_class
和b_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();
}
感谢所有讨论!