1

std::unique_ptrが好きです。これは、メモリリークを防ぐのに役立ちます。これは非常に便利です。ただし、1つの問題があります。それは、コピーの割り当てと構築が許可されていないことです。

この制限はプログラマーの安全に役立ちますが、それもかなり制限されています。コピーの割り当てと構築を使用して、std :: unique_ptrをメンバーとして持つクラスを操作する場合、問題が発生することになります。そのため、コピーの作成と割り当てを使用して、unique_ptrの周りに独自のラッパーを作成しました。これがコピーコンストラクタです:

template<typename T, class Deleter>
PointerSmartSafe<T, Deleter>::PointerSmartSafe(PointerSmartSafe const& pointer_smart_safe_) noexcept : _m_opPointerUnique((_m_opPointerUnique == nullptr) ? new T(*_m_opPointerUnique.get()) : nullptr){

}

そして、これがコピー代入演算子です:

template<typename T, class Deleter>
PointerSmartSafe<T, Deleter>& PointerSmartSafe<T, Deleter>::operator=(PointerSmartSafe const& pointer_smart_safe_) noexcept{
    _m_opPointerUnique = decltype(_m_opPointerUnique)(new T(*_m_opPointerUnique.get()));
    return *this;
}

タイプ(T)として抽象基本クラスを使用することになったまで、すべてが正常に機能しました。次のようなエラーメッセージが表示されました。

error: cannot allocate an object of abstract type 'AbstractBaseClass'

これは私を困惑させます。回避策はありますか?

4

1 に答える 1

7

ただし、1つの問題があります。それは、コピーの割り当てと構築が許可されていないことです。

それは問題ではない。あなたがそれを問題だと思ったら、あなたは何か間違ったことをしているのです。

この制限はプログラマーの安全に役立ちますが、それもかなり制限されています。

意図的に制限しているので、デザインを再考する必要があるかもしれません。

そのため、コピーの作成と割り当てを使用して、unique_ptrの周りに独自のラッパーを作成しました。

あなたが望むのはその時ではなくunique_ptr、あなたは「クローンptr」が欲しいのです

これは私を困惑させます

何が困惑していますか?抽象基本クラスのインスタンスを作成しようとしています。あなたのコードはまた、非抽象ベースをスライスします。それは本質的に安全ではありません。

これは重要なことを教えてくれるはずです。aが保持するオブジェクトのコピーは一般的に行うことはできません。それは、が持っていないunique_ptrコンテキストを必要とします。unique_ptrそのコンテキストは、コピーしたいものを所有するオブジェクト(所有するオブジェクトがオブジェクトの動的タイプを知っている必要がある)またはコピーしたいもの(仮想関数を使用してコピーを作成できる)から取得する必要があります。正しい動的タイプのコンテキスト。)

従来の解決策は、タイプに仮想clone()メンバー関数を追加し、可能な場合はそれを使用することです。

これをコンストラクターに次のように組み込むことができます。

template<typename T>
  auto clone(T* t) -> decltype(t->clone())
  { return t->clone(); }

template<typename T>
  std::unique_ptr<T> clone(T* t, ...)
  { return std::unique_ptr<T>(new T(*t)); }

// ... 

_m_opPointerUnique((_m_opPointerUnique == nullptr) ? clone(_m_opPointerUnique.get()) : nullptr)
于 2013-03-27T13:07:44.840 に答える