
項目 22:Pimpl イディオムを用いる際は特殊メンバ関数を定義する
|
153
コンパイラが生成するムーブ演算は、内包する std::unique_ptr をムーブし、まさに期待通り
に動作するため、Pimpl イディオムを採用したクラスがムーブ対応を考慮するのは自然な流れです。
項目 17 でも述べたように、Widget のデストラクタを宣言するとコンパイラのムーブ演算生成は抑
制されるため、ムーブ対応するには関数を明示的に宣言する必要があります。コンパイラが生成す
るバージョンで動作に問題がなければ、次のように実装するのが良いでしょう。
class Widget { // still in
public: // "widget.h"
Widget();
変わらず「widget.h」
内の宣言
~Widget();
Widget(Widget&& rhs) = default; // right idea,
Widget& operator=(Widget&& rhs) = default; // wrong code!
考え方は正しいが
誤ったコード!
…
private: // as before
struct Impl; 先の例と同様
std::unique_ptr<Impl> pImpl;
};
上例の方法には、デストラクタを持たないクラスを宣言した場合と同じ類の問題があり、その原
因も同じです。コンパイラが生成するムーブ代入演算子は、pImpl が指すオブジェクトを再代入す
る前に破棄する必要がありますが、