【发布时间】:2014-10-07 01:48:39
【问题描述】:
在阅读当前standard 中的move constructor 时,我可以看到以下内容:
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;
}
显然这个程序是不正确的,并且由于两个对象对资源的浅拷贝而具有未定义的行为(终止)。但我的重点是了解程序中生成和使用的默认移动构造函数。我希望这个例子有意义。
在上面的程序中,在应该调用移动构造函数的两种情况下,在我看来编译器都在使用默认的复制构造函数。
基于标准中提到的上述规则,我认为我们应该得到编译器错误,因为现在程序显式尝试调用移动构造函数并且用户没有实现也没有编译器生成默认(隐式),因为上述规则不满足? .
但是,这是在没有任何警告/错误的情况下编译并成功运行的。有人可以解释一下默认(隐式)移动构造函数的概念吗?还是我遗漏了什么?
【问题讨论】:
标签: c++ c++11 move-semantics