今時のc++ (c++11など)でコピー禁止,代入禁止のクラスを作る方法
template <class T> struct CRTPnoncopyable { CRTPnoncopyable(const CRTPnoncopyable&) = delete; CRTPnoncopyable& operator=(const CRTPnoncopyable &) = delete; }; class A : CRTPnoncopyable<A> {};
Boost の noncopyable を使う方法もある *3
#include <boost/core/noncopyable.hpp> class A : boost::noncopyable {};
両者の違いは何か.
それはクラスを継承した際に現れる.
#include <iostream> #include <boost/core/noncopyable.hpp> template <class T> struct CRTPnoncopyable { CRTPnoncopyable(const CRTPnoncopyable&) = delete; CRTPnoncopyable& operator=(const CRTPnoncopyable &) = delete; }; class A1 : boost::noncopyable {}; class A2 : boost::noncopyable {}; class AA: A1, A2 {}; class C1 : CRTPnoncopyable<C1> {}; class C2 : CRTPnoncopyable<C2> {}; class CC : C1, C2 {}; int main() { std::cout << "sizeof(AA) = " << sizeof(AA) << std::endl; std::cout << "sizeof(CC) = " << sizeof(CC) << std::endl; return 0; }
class AAがboost版,class CC がテンプレート版であり,これを実行すると
sizeof(AA) = 2 sizeof(CC) = 1
となる.つまり class CC の方がコンパクトになっている
これはboost版では,コンパイラが Empty Base Optimization を適応できないためである.詳細は以下のページが詳しい
https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E3%82%B3%E3%83%94%E3%83%BC%E7%A6%81%E6%AD%A2%E3%83%9F%E3%83%83%E3%82%AF%E3%82%B9%E3%82%A4%E3%83%B3%28Non-copyable_Mixin%29
実際に使うときはマクロを使うと便利 (2022年8月15日更新)
// マクロの定義 #define NONCOPYABLE(ClassName) ClassName(const ClassName&)=delete; ClassName& operator=(const ClassName&)=delete // 使い方 class MyClass { NONCOPYABLE(MyClass); };
Effective Modern C++ ―C++11/14プログラムを進化させる42項目
posted with amazlet at 18.01.18