【问题标题】:Does move semantic unsuitable to the array in C++11?移动语义是否不适合 C++11 中的数组?
【发布时间】:2013-09-04 11:27:46
【问题描述】:

我测试 unique_ptr 如下

#include <iostream>
#include <memory>
using namespace std;

class A
{
public:
    virtual ~A() {}
    virtual void print()
    {
            cout << "A::Print()" << endl;
    }
};

class B : public A
{
public:
    virtual ~B() {}
    virtual void print()
    {
            cout << "B::Print()" << endl;
    }
};


int main()
{
    A a;
    B b;

    A* arr[2] = {&a, &b};
    arr[0]->print();
    arr[1]->print();

    unique_ptr<A*[]> ptr(move(arr));
    /*
    unique_ptr<A*[]> ptr(new A*[2]{&a, &b});
    */
    ptr[0]->print();
    ptr[1]->print();

    return 0;
}

它得到类似 (g++ 4.7.3) 的结果

A::Print()
B::Print()
A::Print()
B::Print()
Aborted (core dumped)

ptrarr 似乎指向同一个东西,并且在调用时 析构函数,已经被删除了两次。

为什么移动语义在这里不生效?

是不适合数组还是和unique_ptr有关?

【问题讨论】:

  • 另一个人至少应该得到一个紫外线,他在技术上首先回答:)

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


【解决方案1】:

这里的问题是unique_ptr&lt;T&gt; 假定它管理的对象是用new 分配的。因为它是在堆栈上静态分配的,所以unique_ptr 析构函数在尝试delete 你的数组时会崩溃。

无论如何,我不确定你想用这个unique_ptr 达到什么目的。唯一指针确保托管对象在作用域结束时被删除,但分配在堆栈上的数组在作用域结束时被删除,本质上。你会不会没有unique_ptr,你的代码会发挥同样的作用,而且无论如何都不会泄漏。

【讨论】:

    【解决方案2】:

    这里的问题是这里没有动态分配的内存(永远不要使用 new 关键字)。所以 unique_ptr 试图释放从未分配过的内存(调用 delete on)。我的建议是尝试编写更简单的代码,因为你做了很多非常规的事情。

    1. 你无缘无故存储A*,它们会被自动删除,我想不出有什么好的理由将它们存储为指针
    2. 您不使用任何标准库容器,您可以使用 std::array&lt;A,2&gt; 代替 c 样式数组
    3. 另外我猜你只是把它作为一个测试,所以我真的不能告诉你在这里想要达到什么目标

    【讨论】:

    • @CLS 当你使用 STL 时,事情往往会更好,看起来更漂亮
    • 我不明白你的意思...我刚刚阅读了 STL 并且对 unique_ptr 进行了测试,太傻了以至于我忘记了 delete 一个未使用 @987654324 分配的对象@ 是未定义的行为,我错误地认为这可能是移动语义的问题
    • @CLS 有时会发生在每个人身上;)
    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2014-08-16
    • 2012-08-20
    • 2014-03-18
    相关资源
    最近更新 更多