#include <iostream>
class BarParent
{
public:
int x;
virtual void fuz() = 0;
};
class BarChild : public BarParent
{
public:
BarChild(int new_x){x = new_x;}
virtual void fuz(){}
};
class FooParent
{
public:
BarParent* p_barPar;
FooParent (BarChild* new_p_bar)
{
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
};
class FooChild: public FooParent
{
public:
BarChild barChild;
FooChild(int new_x):FooParent(&barChild), barChild(new_x){}
};
int main()
{
FooChild foo(60);
BarChild bar(99);
FooParent fooP(&bar);
}
输出:
-548726160
99
我理解为什么我得到这个结果(未定义的行为),barChild
在它被初始化之前使用。我的问题是处理这个问题的“正确”是什么。
答案 0 :(得分:2)
这是需要修复 design 而不是代码的情况。
按照你自己的设计:
BarChild
之前构建FooParent
。FooParent
之前构建FooChild
。FooChild
之前构建BarChild
。当您希望FooParent
和FooChild
同时引用同一个Bar对象时 - 正如您在代码中尝试一样 - 设计父类来管理它。
一个示例解决方案:
FooParent (BarChild* new_p_bar)
{
if ( new_p_bar == NULL )
new_p_bar = new BarChild;
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
此处,FooChild
不需要自己的此对象实例。
答案 1 :(得分:0)
尊重初始化顺序。
您可以在BarParent中创建一个函数来设置指针p_barPar。在FooChild的构造函数中调用该函数。
你有什么理由不能让barChild(在FooChild中)成为一个指针吗?
答案 2 :(得分:0)
我认为你必须找到另一个例子:这个是错误的,因为RAIII原则没有强制执行:FooParent
持有一个它不能控制的值的指针。此设置失败的一个有趣示例是slicing problem。
答案 3 :(得分:0)
快速而肮脏的解决方案:
class FooChild: private BarChild, public FooParent
{
public:
FooChild(int new_x): BarChild(new_x), FooParent(this) {}
};