web-dev-qa-db-ja.com

shared_ptrを指定してオブジェクトを適切に複製する方法

カスタムクラスEventのオブジェクトの複製を作成しようとしています。私はその割り当てから取得したオブジェクトへの共有ポインターを持っています:

_std::shared_ptr<Event> e = std::make_shared<Event>();
_

eの真の複製(ポインタのコピーだけではない)を取得するために、私は試しました:

_std::shared_ptr<Event> o = std::make_shared<Event>(*e);
_

しかし、これが正しい方法かどうかはわかりません。eを削除すると、o...も削除されるようです。

ところで、私はコピーコンストラクターEvent::Event(const Event &orig)を定義していませんが、コンパイラーはデフォルトのコピーコンストラクターを提供しているため、これは必要ありません。イベントクラスには変数のみが含まれ、それ以上のポインタは含まれません。

18
Marc

std::make_sharedは、オブジェクトを作成し、すべての引数をコンストラクターに渡す単純なテンプレート関数です。

template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args)
{
  return shared_ptr<T>( new T( std::forward<Args>( args )... ) );
}

あなたの特定のケースでは:

std::shared_ptr<Event> o = std::make_shared<Event>(*e);

オブジェクトがコピーされます。

あなたのコードがそのような場合:

void foo() {
    // create new object using default constructor
    std::shared_ptr<Event> e = std::make_shared<Event>();
    // create new object using copy constructor constructor
    std::shared_ptr<Event> o = std::make_shared<Event>(*e);
}

もちろん、範囲外になると、両方のオブジェクトが破棄されます。

12
BЈовић

あなたが試したものは正しく機能するはずですif*eの動的型はEventであり、Eventから派生した一部のクラスではありません。 (*eが実際にEventから派生したオブジェクトである場合、*eの基本クラス部分のコピーとして新しいEvent(派生型ではない)を作成します。つまり、*eを「スライス」します)。

make_shared<Event>()を使用してeを作成するので、この場合は実際にEventであることを知っているので、std::make_shared<Event>(*e)はを所有する新しいshared_ptrを作成する必要があります*eのコピー。

5
Jonathan Wakely