-2

次のように 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)

ptrと同じものを指すように見えarr、デストラクタを呼び出すと、2回削除されました。

ここで移動セマンティックが有効にならないのはなぜですか?

配列には不向きですか、それともunique_ptrについてですか?

4

2 に答える 2

4

ここでの問題は、unique_ptr<T>それが管理するオブジェクトが で割り当てられたと想定していることnewです。代わりにスタックに静的に割り当てられるため、デストラクタは配列unique_ptrを試行するとクラッシュします。delete

unique_ptrとにかく、これで何を達成しようとしているのかわかりません。一意のポインターにより、マネージド オブジェクトはスコープの最後で確実に削除されます、スタックに割り当てられた配列は本質的にスコープの最後で削除されます。ないunique_ptr場合、コードは同じように機能し、とにかくリークしません。

于 2013-09-01T03:14:18.130 に答える
3

ここでの問題は、動的に割り当てられたメモリがここにないことです (決して new キーワードを使用しないでください)。したがって、unique_ptr は割り当てられなかったメモリを解放しようとしています (delete を呼び出します)。非常に型にはまらないことを大量に行うため、より単純なコードを作成することをお勧めします。

  1. 理由もなく保存A*します。それらは自動的に削除されます。ポインタとして保存する正当な理由は考えられません
  2. 標準ライブラリ コンテナーは使用しません。C std::array<A,2>スタイルの配列の代わりに a を使用できます。
  3. また、あなたがこれをテストとして作成しただけだと思う​​ので、ここで何を達成しようとしているのか本当にわかりません
于 2013-09-01T03:14:51.857 に答える