0

这是导致问题的代码:

class Base
{
public:
    virtual void fun()
    {
        cout<<"Base";
    }
};
class Der:public Base
{
    Base &pb;
public:
    Der(Base&b):pb(b){}
    virtual void fun()
    {
        cout<<"Der...";
        pb.fun();
    }
};
int main()
{
    Der(Der(Base())).fun();
    return 0;
}

运行这段代码,结果显示“Der...Base...”!这太神奇了,我想不通为什么结果不是“Der...Der...Base”,这在逻辑上是正确的?!然后我用 Der 类中的成员替换并将Base&pb代码Base*pb更改为合法,最后输出正确,即“Der...Der...Base”!调试了一下代码,发现在使用的时候Base&pb,Der的构造函数只跑了一次,使用Base*pb的时候,构造函数跑了两次正确!谁能向我解释发生了什么以及为什么?

4

2 回答 2

1

Der(Der(Base())).fun()表达式中,内部Der(Base())产生一个rvalue- 编译器通过使用复制省略优化代码并删除不必要的对象复制。

于 2012-11-18T14:11:29.263 回答
0

除了@icepack的回答和评论中的以下讨论(摘要:代码Der(der)是一个演员,可能会或可能不会使用构造函数实现;在你的情况下不是),一个解决方法:你应该做出你的意图通过不使用构造函数来清除。

我会将您的代码重写为如下内容:

class Base
{
public:
    virtual void fun()
    {
        cout<<"Base";
    }
};

class Der:public Base
{
    Base &pb;
    Der(Base& b) : pb(b) {}
public:
    static Der Decorate(Base&& b){ return Der(b); }
    virtual void fun()
    {
        cout<<"Der...";
        pb.fun();
    }
};

int main()
{
    Der::Decorate(Der::Decorate(Base())).fun();
    return 0;
}

输出:Der...Der...Base)。


更改代码以接受指针很容易

class Base
{
public:
    virtual void fun()
    {
        cout << "Base";
    }
};

class Der : public Base
{
    Base* pb;
    Der(Base* b) : pb(b) {}
public:
    static Der Decorate(Base* b){ return Der(b); }
    virtual void fun()
    {
        cout << "Der...";
        pb->fun();
    }
};

int main()
{
    Der::Decorate(&Der::Decorate(&Base())).fun();
    return 0;
}
于 2012-11-18T15:01:53.837 回答