gpt4 book ai didi

c++ - 为什么移动语义与动态内存分配中的浅拷贝具有相同的行为?

转载 作者:太空宇宙 更新时间:2023-11-04 15:32:46 24 4
gpt4 key购买 nike

在处理动态内存分配的类中,浅拷贝基本上导致程序删除资源两次。在移动操作中,原始指针不再指向资源,但是为什么在移动语义中会出现相同的行为呢?例如:

#include <utility>
#include <cstring>
using namespace std;
class MyString
{
char* cstr;
public:
MyString(const char* arg)
: cstr(new char[strlen(arg)+1])
{
strcpy(cstr, arg);
}
MyString(MyString&&) = default;
MyString& operator=(MyString&&) = default;
MyString(const MyString&) = delete;
MyString& operator=(const MyString&) = delete;
~MyString()
{
delete[] cstr;
}
};

int main()
{
MyString S1{"aaa"};
MyString S2 = move(S1); // error

}

我尝试了 3 种不同的编译器,得到了相同的结果。

最佳答案

隐式生成的移动构造函数移动构造每个成员。你的成员是一个指针。移动指针(或任何其他原始对象)与复制它相同。

因此,由于您的移动构造函数除了移动指针外什么都不做,从 MyString 移动的对象仍将指向与移动到 MyString 的对象相同的指针对象目的。当两者都被销毁时,析构函数将尝试删除指针对象两次。

您需要遵循规则 5:如果需要实现析构函数、移动/复制构造函数、移动/复制赋值中的任何一个,那么它们很可能都需要实现(或删除)。您已经实现了析构函数来删除拥有的指针,因此您必须实现移动构造函数(和其他构造函数),以便从中移动(或从中复制)的对象不再指向它不再拥有的对象。

Why move semantics have the same behavior as shallow copy in dynamic mem allocation?

因为移动只是浅拷贝的另一种说法。移动构造函数和赋值运算符将被赋予自定义实现,以防需要清理从对象移出的对象以保持类不变。就像复制构造函数和复制赋值运算符一样,可以进行不破坏类不变性的深层复制。

关于c++ - 为什么移动语义与动态内存分配中的浅拷贝具有相同的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45384264/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com