在阅读有关move constructor从目前standard,我可以看到以下这一点:了解默认移动构造函数定义
12.8复制和移动类对象
如果一个类的定义X没有明确声明一个移动构造函数,只有当且仅当
- X没有用户声明的复制构造函数,
- X没有用户声明的复制赋值运算符,
- X没有用户声明的移动赋值运算符,并且
- X没有用户声明的析构函数。[注意:当移动构造函数未被隐式声明或显式提供时,否则将调用移动构造函数的表达式可能会调用复制构造函数。 - 结束注意]
我觉得注意部分清楚地提到,默认移动构造函数的后退将是复制构造函数。为了理解这个概念,我编写了一个小程序来理解这个概念。
#include<iostream>
struct handleclass {
public:
handleclass():length{0}, p{nullptr} {}
handleclass(size_t l):length{l},p{new int[length]} { }
~handleclass() { delete[] p; }
size_t length;
int* p;
};
handleclass function(void) {
handleclass x(10);
return x;
}
int main() {
handleclass y;
std::cout<<y.length<<std::endl;
y = function();
std::cout<<y.length<<std::endl;
handleclass a;
handleclass b(10);
a = std::move(b);
return 0;
}
显然这个方案是不正确,将由两个对象有不确定的操作(终止)由于资源的浅拷贝。但我的重点是了解程序中生成和使用的默认移动构造函数。我希望这个例子有意义。
在上面的程序中,在移动构造函数应该被调用的两种情况下,在我看来,编译器正在使用默认的拷贝构造函数。
根据标准中提到的上述规则,我认为我们应该得到编译器错误,因为现在程序显式地尝试调用移动构造函数,并且用户既没有执行也没有编译器生成默认(隐式),如上面的规则不满足?。
但是,这是得到编译没有任何警告/错误,并成功运行。有人可以解释有关默认(隐式)移动构造函数的概念吗?或者我错过了什么?
-fno-elide-constructors选项可用于禁用g ++的复制elision – 2014-10-07 02:01:16