【发布时间】:2023-04-08 02:23:01
【问题描述】:
我在移动语义方面有点挣扎。我阅读了很多关于该主题的内容,但是,有两个具体问题我没有找到任何答案,因此想向您介绍它们。
首先,我有以下示例代码:
#include <iostream>
#include <cstddef>
class A
{
public:
A *ptr;
virtual ~A()
{
std::cout << "dtor" << std::endl;
delete ptr;
ptr=nullptr;
}
};
main()
{
A x, y;
x.ptr = &y;
}
// compile and link like this with g++: g++ -std=c++0x -lstdc++ code.cc
A 类可以拥有自己的成员。我使用这种“复合模式”概念来构建层次结构。但是,在这种情况下,当对象 x 被析构时,其析构函数会删除指向对象 y 的指针。当最终对象 y 应该被破坏时,它已经产生了错误......我该如何解决这个问题?
第二种情况如下:
main()
{
A x, y;
y = std::move(x);
std::cout << "x.ptr: " << x.ptr << std::endl;
std::cout << "y.ptr: " << y.ptr << std::endl;
}
在这里,我可以看到两个引用是相等的,这意味着两者都存在。我虽然 std::move 将内容从 x 移动到 y。我原以为 x.ptr 是“空的”....?
提前致谢!
干杯
【问题讨论】:
-
你有一个
delete和零个news。 -
测试时我得到了 x.ptr 和 y.ptr 作为空值。第二个我也没有收到任何错误。
-
解决第二种情况:
std::move本身并没有做太多事情,数据的 移动 由移动构造函数完成,默认移动构造函数是其中的成员- 明智的移动,但对于原语等(如指针)只是一个副本。因此,它不会将x.ptr设置为“空” -
在你的析构函数末尾做
ptr=nullptr;是没有意义的。 -
解决第一种情况:这就是为什么原始指针
A*是表示所有权的不好方式的原因。unique_ptr和shared_ptr在“拥有”另一个对象时是首选,因为它们在语义上都很清晰,并且有明确定义的清理方式。
标签: c++ c++11 destructor move move-semantics