unique_ptr<T>
前方宣言型に aを使用する場合T
、unique_ptr
デストラクタには is complete が必要ですが、次の表によるT
と移動代入演算子 (and ) も必要です。reset
https://stackoverflow.com/a/6089065/1794803
したがって、pImpl
イディオムを正しく実装するには、 thedelete
と theを宣言する必要がありますmove assignment method
(副作用として、インライン化されていないことを示します)。
class impl_t;
class A
{
std::unique_ptr<impl_t> p_impl;
public:
// Implement in A.cpp as A::~A() = default;
~A();
// Implemented in A.cpp as A& operator=(A&&) = default;
A& operator=(A&& he);
};
しかし、std::unique_ptr
は動的メモリの RAII ソリューションであり、pImpl
既にクラス内にいて、とにかくデストラクタを作成する必要があるため、クラスはすでに RAII であるため、生のポインタを管理するだけの方がよいのではないでしょうか? ?の観点からのようにp_impl
:
class impl_t;
class A
{
impl_t* p_impl;
public:
~A(); // The destructor must be written anyway.
// The omitted move assignment destructor doesn't cause UB.
};
それはより良い解決策ではありませんか?(+クラスをコピー可能/移動可能にするかどうかを指定する場合は、独自のコピー/移動演算子を定義または削除します。ただし、それは「意識的な選択」です。ただし、移動割り当てを書き込まないでくださいunique_ptr
。エラーです)。
a のみを使用すると、とにかく宣言する必要があるデストラクタunique_ptr
に書かれた a を節約できます。delete p_impl
unique_ptr
例外の場合でも破棄されるローカル動的オブジェクトには優れた選択肢ですが、「属性」の場合、移動代入演算子を書き直す必要があることを覚えていなければ、UB を取得する可能性しかありません。