0
#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在它被初始化之前被使用。我的问题是处理这个问题的“权利”是什么。

4

4 回答 4

2

这是需要修复设计而不是代码的情况。

通过您自己的设计:

  • ABarChild必须在 之前构造FooParent
  • AFooParent必须在 a 之前构造FooChild
  • AFooChild必须在 a 之前构造BarChild

当您想要两者FooParentFooChild引用同一个 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不需要它自己的这个对象的实例。

于 2013-03-31T20:43:14.210 回答
0

尊重初始化的顺序。

您可以在 BarParent 中创建一个函数来设置指针 p_barPar。在 FooChild 的构造函数中调用该函数。

是否有任何理由不能让 barChild(在 FooChild 中)也成为指针?

于 2013-03-31T20:30:40.973 回答
0

我认为您将不得不找到另一个示例:这个示例是错误的,因为未强制执行 RAIII 原则:FooParent将指针保存在它无法控制的值上。这个设置失败的一个有趣的例子是切片问题

于 2013-03-31T20:49:16.070 回答
0

快速而肮脏的解决方案:

class FooChild: private BarChild, public FooParent
{
public:
        FooChild(int new_x): BarChild(new_x), FooParent(this) {}
};
于 2013-03-31T21:16:17.830 回答