我应该从动态指针中删除一个 moved 吗

Should i delete a moved from dynamic pointer

我了解如何移动对象,例如:

int a(5), b(6);
int c(std::move(a)); // move constructor
c = std::move(b);    // move assignment

我了解自定义移动构造函数的常见实现(它获取动态指针的所有权并将移出指针设置为 nullptr。)

但是我还没有发现任何关于移动动态分配的指针本身的信息。我需要确认以下代码是否合法:

int *p(new int(42));
int val(std::move(*p));
delete p; // I think this is no longer necessary. Is it?

那么,是否允许移动动态指针?

std::move 不移动任何东西。它只是将左值引用转换为右值引用。

在你给出的例子中,指针p没有移动到任何地方。

顺便说一句。请不要处理原始指针 - 请改用 std::unique_ptr

这为 int 分配内存,将 int 初始化为值 42 并将该内存的地址存储在 p 中。

int *p(new int(42));

这会将 p 指向的 int 转换为 int&&,然后从该 r-value 引用构造 int val。由于 int 是整数类型,因此从 r 值构造(即移动)等同于副本(这是标准中强制要求的)

int val(std::move(*p));

是的,这个还是有必要的

delete p;// i think this is no longer necessary. is it ?

在你的第二个例子中,你的代码本质上是将一个整数的值复制到另一个。您不是在移动指针,而是在移动指针指向的整数。

int a = 42;
int b = std::move(a);

std::cout << a << " : " << b << std::endl; // prints 42 : 42

移动整数就是复制它们。

即使你移动了指针,复制的指针的值:

int* a = new int{42};
int* b = std::move(a);

std::cout << *a << " : " << *b << std::endl; // prints 42 : 42
std::cout << std::boolalpha << (a == b) << std::endl; // prints true

所以移动原始指针也在复制它们。 您仍然需要删除 p 指针。

每一个新的,都有一个删除。

如果您不想自己删除它,请考虑 std::unique_ptr,它了解移动语义。

原始指针、int、float 等内置类型不了解移动语义,移动它们只会简单地复制它们。

在您的示例中,移动语义的使用很简单,因为您仅使用原始类型和原始指针。 std::move真是无所事事。

当您的对象属于支持移动操作(移动构造函数、移动赋值等)的 class 或与其他 classes/ 函数交互时,移动语义会有所不同这样做。

通常,从对象移动后(不是 std::move 本身的结果,而是后续调用的结果),对象是仍然活着并处于有效状态,尽管它已被剥夺任何托管内容。对象的破坏仍有待完成,它仍然是一个有生命的对象。

请注意,您很少看到带有原始指针的移动语义。常见于自动存储对象或智能指针。那只是因为移动语义可以很好地发挥作用。