为什么在未命名对象只有活着直到完整表达式结束时才需要移动构造函数? 如果我们有这个代码:
class Example6 {
string* ptr;
public:
Example6 (const string& str) : ptr(new string(str)) {}
~Example6 () {delete ptr;}
// move constructor
Example6 (Example6&& x) : ptr(x.ptr) {x.ptr=nullptr;}
// move assignment
Example6& operator= (Example6&& x) {
delete ptr;
ptr = x.ptr;
x.ptr=nullptr;
return *this;
}
};
int main () {
Example6 bar = Example6("ple"); // move-construction
return 0;
}
我们有一个Rvalue引用作为移动构造函数和赋值操作的参数。在这种情况下,bar
的移动构造函数在初始化为同一个类的临时函数时被调用。我不明白的是:由于临时表具有完整表达式的生命周期,为什么需要移动构造函数而不是复制构造函数?我的意思是,隐式定义的移动构造函数和赋值运算符" erase"来自临时的数据,即使这些数据在分号后都会被销毁,那么为什么你需要一个移动构造函数,它与复制构造函数有些相同...为什么需要从临时数据中删除数据无论如何,在分号后被摧毁?
答案 0 :(得分:1)
C ++添加移动构造函数主要是为了帮助提高性能。在不使用移动构造函数的情况下,可以进行适当的资源管理。实际上,这就是C ++在引入移动构造函数之前用来做的事情。
复制然后销毁临时文件的问题是被调用的复制构造函数不知道它被赋予临时复制权。因此,复制构造函数必须复制数据,就好像它的源不是临时的,可能在复制对象的过程中分配额外的资源。
当编译器知道你要复制一个临时文件时,它会让你知道你可以收获尽可能多的内部结构,这可能会节省你一些昂贵的分配。
答案 1 :(得分:0)
为什么需要从临时内容中删除数据 无论如何在分号后被摧毁?
不,这不是您想要移动构造函数的原因。
正如你所说,暂时的价值不重要因为它是暂时的,所以移动构造者可以“偷”"临时的数据,以避免昂贵的分配等。这是什么,它是什么给你提供更好的移动与复制性能,而不是因为数据将被删除。
移动是为了获得性能,而不是确保数据被删除"。
答案 2 :(得分:0)
原因如下:
请注意,移动构造不会消除复制省略的需要。原始类型的移动与副本一样昂贵!