Zac*_*ary 0 c++ copy-constructor rvo
我正在尝试测试RVO和右值参考.这是代码:
#include <iostream>
using namespace std;
class B{
public:
int i;
B(){
i = 0;
cout << "B() " << i << endl;
}
B(const B& b){
i = 1;
cout << "B(const B&) " << i << endl;
}
B(const B&& b){//if remove this constructor, then call B(const B& b)
i = 2;
cout << "B(const B&&) " << i << endl;
}
~B(){
cout << "~B() " << i << endl;
}
};
B f(){
B b;
return b;
}
int main(){
B b = f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
B() 0
B(const B&&) 2
~B() 0
~B() 2
Run Code Online (Sandbox Code Playgroud)
环境:WIN8,Visual Studio 2012 Express
这意味着调用移动构造函数:B(const B &&).提出两个问题:
如果我删除B(const B &&),则调用B(const B&).奇怪的输出:
B()0
B(const B&)1
~B()0
~B()1
以下是我发现的参考资料:
编辑:
在移动构造函数应该B(B &&) .这就是移动构造函数被称为复制构造函数的原因.
为什么RVO不适用于此?
它不仅仅是执行优化.使用时,g ++在这里使用RVO -O2.您应该在编译器上启用优化以对其进行测试.但请注意,即使某些编译器可能会应用RVO,也不是必需的,因此您可能会看到使用不同编译器的不同结果.
为什么不调用移动构造函数:B(const B&)?
那是一个复制构造函数.它调用移动构造函数,这是一个更好的匹配.
如果我删除B(const B &&),则调用B(const B&).奇怪的!
不,这并不奇怪.如果定义了复制构造函数,则编译器不会隐式定义移动构造函数.因此,编译器正在选择复制构造函数,因为没有可用的移动构造函数.
请注意,您的移动构造函数应采用非const rvalue引用:
B(B&& b) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
否则,你最终会像在复制构造函数中那样做.