以下是导致问题的代码:
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”这在逻辑上是对的?!
然后我用Base&pb
替换Der Base*pb
类中的成员并将代码更改为legal,finnaly输出正确,这是“Der ... Der ... Base”!
我调试代码并发现当我使用Base&pb
时,Der的构造函数在使用Base*pb
时只运行了一次,构造函数正确运行了两次!
谁能向我解释发生了什么以及为什么?
答案 0 :(得分:1)
在Der(Der(Base())).fun()
表达式中,内部Der(Base())
产生rvalue
- 编译器使用copy elision优化代码并删除不必要的对象复制。
答案 1 :(得分: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;
}
更改代码以接受指针is easy:
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;
}