【问题标题】:Who is responsible for deletion of heap allocated object when moving it?谁负责在移动堆分配对象时删除它?
【发布时间】:2014-10-08 18:36:58
【问题描述】:

用new创建类,然后执行类的move构造函数会发生什么?原作者还负责删除吗?下面的示例运行良好(http://ideone.com/rS2LR9),但它不应该在第二个范围内崩溃,因为所有者在向量之前超出范围并因此删除了对象?

我显然在这里误解了一些东西,std::move之后的所有权会发生什么?

#include <iostream>
#include <memory>
#include <vector>
#include <utility>

class Owner {
public:
Owner() : data_(new int(1)) {}
int& get() {return *data_;}
private:
std::unique_ptr<int> data_;

Owner(const Owner&) = delete;
void operator=(const Owner&) = delete;
};

int main()
{
    {
        Owner owner;
        std::vector<int> test;
        test.emplace_back(std::move(owner.get()));
        std::cout << test[0] << std::endl;
    }

    {
        std::vector<int> test;
        {
                Owner owner;
                test.emplace_back(std::move(owner.get()));
        }
        std::cout << test[0] << std::endl;
    }

    {
        Owner owner;

        {
            std::vector<int> test;
            test.emplace_back(std::move(owner.get()));
            std::cout << test[0] << std::endl;
        }
    }
}

【问题讨论】:

  • 移动的对象处于有效但未指定的状态。为此,一旦对象超出范围,将调用移动对象的析构函数。一个对象的移动并不意味着这个对象真的被移动了,而是另一个对象窃取了被移动对象的内存。

标签: c++ c++11 move unique-ptr


【解决方案1】:

您没有在此处移动任何数据。当您调用 Owner::get() 时,您将公开对 int 的引用,而当您在该引用上调用 std::move() 时,您只是在进行微不足道的转换。 std::vector::emplace_back() 没有什么可以“窃取”Owner,因为 int 没有移动构造函数。

我猜您认为Owner 中的std::unique_ptr 参与了这些操作,但事实并非如此;您正在取消引用该指针,但从未尝试移动其内容。为此,您必须调用std::unique_ptr 的移动构造函数或赋值运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多