C++継承用noncopyableクラスの実装
1622 ワード
C++11でクラスのコピー動作を禁止するには、対応する関数を
従来の規格では、対応する関数を
ただし、通常のクラスでは、クラスのメンバー関数宣言を表示しないと、クラスがコピーできないタイプかどうかはわかりません.C++では,継承の技法を用いて
このクラスを継承するだけで派生クラスがコピーできないことを保証できます.
ここで利用するのはC++の合成コンストラクタで、派生クラスがデフォルトのコンストラクタ/解析関数/コピーコンストラクタ/賦値演算子を呼び出すと、まずベースクラスのデフォルトのコンストラクタ/解析関数/コピーコンストラクタ/賦値演算子を呼び出すが、ベースクラスではコピーコンストラクタと賦値演算子が使用できないため、派生クラスはコピー動作を行うことができない.同時に、NonCopyableクラスにデフォルトのコンストラクタ/コンストラクタを宣言し、派生クラスでベースクラス(NonCopyable)の対応する関数を呼び出してベースクラス部分をコンストラクタ/コンストラクタできるようにします.
もちろん,必要であれば派生クラスはコピー構造関数と付与演算子を定義することも可能であるが,この行為は許容されるが,論理的に矛盾し,プログラマーのミスである.
参照boost::noncopyableの実装
delete
に設定するだけでよいので、標準ライブラリのstd::unique_ptr
を参照してください.unique_ptr (const unique_ptr&) = delete;
unique_ptr& operator= (const unique_ptr&) = delete;
従来の規格では、対応する関数を
private
関数としていた.ただし、通常のクラスでは、クラスのメンバー関数宣言を表示しないと、クラスがコピーできないタイプかどうかはわかりません.C++では,継承の技法を用いて
noncopyable
クラスを簡単に実現できる.class NonCopyable {
protected:
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
NonCopyable() = default;
~NonCopyable() = default;
};
このクラスを継承するだけで派生クラスがコピーできないことを保証できます.
class A : public NonCopyable {};
int main() {
A a1;
A a2 = a1; //
A a3;
a3 = a1; //
return 0;
}
ここで利用するのはC++の合成コンストラクタで、派生クラスがデフォルトのコンストラクタ/解析関数/コピーコンストラクタ/賦値演算子を呼び出すと、まずベースクラスのデフォルトのコンストラクタ/解析関数/コピーコンストラクタ/賦値演算子を呼び出すが、ベースクラスではコピーコンストラクタと賦値演算子が使用できないため、派生クラスはコピー動作を行うことができない.同時に、NonCopyableクラスにデフォルトのコンストラクタ/コンストラクタを宣言し、派生クラスでベースクラス(NonCopyable)の対応する関数を呼び出してベースクラス部分をコンストラクタ/コンストラクタできるようにします.
もちろん,必要であれば派生クラスはコピー構造関数と付与演算子を定義することも可能であるが,この行為は許容されるが,論理的に矛盾し,プログラマーのミスである.
class A : private NonCopyable {
public:
A(int i) : i_(i) {}
A(const A& rhs) : i_(rhs.i_) {}
A& operator=(const A& rhs) { i_ = rhs.i_; return *this; }
void show() { cout << i_ << endl;}
private:
int i_;
};
int main() {
A a1(3);
A a2 = a1; // OK
a2 = a1; // OK
a2.show();
return 0;
}
参照boost::noncopyableの実装