C++ 既然临时对象被销毁了,为什么还需要移动构造函数呢?
当未命名的对象在完整表达式结束之前都是活动的时,为什么还需要移动构造函数呢? 如果我们有这个代码:C++ 既然临时对象被销毁了,为什么还需要移动构造函数呢?,c++,C++,当未命名的对象在完整表达式结束之前都是活动的时,为什么还需要移动构造函数呢? 如果我们有这个代码: class Example6 { string* ptr; public: Example6 (const string& str) : ptr(new string(str)) {} ~Example6 () {delete ptr;} // move constructor Example6 (Example6&& x) :
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;
}
我们有一个右值引用作为move构造函数和赋值操作的参数。在这种情况下,bar
的move构造函数在初始化为同一类的临时构造函数时被调用。我不明白的是:既然临时表达式有完整表达式的生存期,为什么需要移动构造函数而不是复制构造函数?我的意思是,隐式定义的移动构造函数和赋值运算符“擦除”临时表达式中的数据,即使这些数据都会在分号后被销毁,那么为什么需要一个移动构造函数,它与复制构造函数的作用有些相同。。。为什么需要从分号之后被销毁的临时文件中删除数据
为什么需要从获取的临时文件中删除数据
在分号之后被销毁了
不,这不是你想要移动构造函数的原因
正如您所说,临时值无关紧要,因为它是临时的,所以移动构造函数可以“窃取”临时值的数据,以避免昂贵的分配等。这就是它的意义所在,这是移动与复制的性能更好的原因,而不是因为数据将被擦除
移动是为了提高性能,而不是确保数据被“擦除”。C++添加移动构造函数主要是为了帮助提高性能。正确的资源管理完全不需要使用移动构造函数。事实上,这就是C++在移动构造函数的引入之前使用它的方式。 复制然后销毁临时对象的问题是,被调用的复制构造函数不知道它被赋予了一个要复制的临时对象。因此,复制构造函数必须复制数据,就像它的源不是临时的一样,在复制对象的过程中可能会分配额外的资源 当编译器知道您将要复制一个临时文件时,它会让您知道您可以按照自己的意愿获取尽可能多的内部文件,从而可能为您节省一些昂贵的分配。原因如下:
请注意,移动构造不会消除复制省略的需要。移动基本类型和复制一样昂贵 因为move构造函数不仅适用于临时对象,它还适用于与之匹配的任何对象。有时,您甚至没有一个复制构造函数来确保只使用移动语义(比如使用
std::unique_ptr
)。可能存在@JamesRoot的重复,我不太确定。。我的问题主要是关于复制和移动函数之间的混淆,而这个问题专门问什么是移动语义。不过我不确定。移动的主要目的是避免浪费复制资源的时间,并更好地使用不可复制的对象。想象一下,如果您的字符串有2G字节长。复制它并销毁旧的将是最慢的,或者在最坏的情况下导致分配失败/延迟分配崩溃。或者如果Example6
不可复制,则main
甚至无法编译。移动是为了获得性能。。。不仅如此。它还使我们能够移动之前无法复制的东西(例如,在移动语义之前调整std::vector
的大小是不可能的),我个人认为这比可能的性能提升更令人兴奋。合同++是意外还是故意的?打字错误。智能手机并不那么聪明。更正。