kay*_*ahr 8 c++ move-semantics c++11
作为一个C++新手,我在理解C++ 11的新Move-Constructor时遇到了问题,我希望有人可以解释我偶然发现的具体情况.我们来看看这个示例代码:
#include <iostream>
using namespace std;
class Model {
public:
int data;
Model(int data) : data(data) { cout << "Constructor" << endl; }
Model(Model&& model) { cout << "Move constructor" << endl; }
~Model() { cout << "Destructor" << endl; }
private:
Model(const Model& model);
const Model& operator=(const Model&);
};
Model createModel(int data) {
return Model(data);
}
int main(void) {
Model model = createModel(1);
cout << model.data << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个createModel函数,它应该将模型作为临时右值返回,我想将它分配给左值.我不希望编译器创建Model对象的副本,因此我将复制构造函数定义为私有,并且我对赋值运算符执行相同操作以确保不复制任何数据.执行此操作后,代码正确不再编译,因此我添加了Move构造函数,现在它再次编译.但是当我运行程序时,我得到了这个输出:
Constructor
1
Destructor
Run Code Online (Sandbox Code Playgroud)
所以从未调用过移动构造函数.我不明白为什么我必须指定移动构造函数,以便在运行时根本不使用它时能够编译该程序.
是因为编译器(GCC 4.8.2)优化了移动构造函数吗?或者这里有其他魔术吗?
那么有人可以解释一下上面的代码究竟发生了什么?代码做我想要的但我真的不明白为什么.
您的计划可能会发生两件事:
model.出于同样的原因,编译器可以省略这两个步骤:
当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动
还有其他情况会发生复制/移动省略(参见C++ 11中的§12.8/ 31).请注意,复制/移动省略完全是可选的 - 编译器不必这样做.
请注意,只要编译器不会改变程序的行为(在as-if规则下),就允许编译器绝对优化任何东西.标准中明确提到复制/移动省略的原因是,如果复制/移动构造函数有副作用,它可能会改变程序的行为.即使编译器改变了程序的行为,也允许编译器执行此优化.这就是为什么你的复制/移动构造函数永远不应该有副作用,因为那时你的程序将有多个有效的执行路径.
您可以传递该-fno-elide-constructors选项以gcc确保永远不会执行此优化.
| 归档时间: |
|
| 查看次数: |
236 次 |
| 最近记录: |