boost::noncopyable はクラスのコピーコンストラクタとコピー代入演算子を隠蔽するC++のイディオムを簡単に実装するためのユーティリティーです。たとえば、次のような実装は…
class Widget
{
...
private:
Widget(const Widget&);
Widget& operator = (const Widget&);
};
と書く代わりに、boost::noncopyableを使うと…
class Widget : boost::noncopyable
{
...
};
となります。boost::noncopyableクラスですでにコピーコンストラクタとコピー代入演算子が隠蔽されているので、Widgetクラスでいちいちこれらを書かなくていいのです。
とまあ、ここまではよいのですが、最近、次のようなすこし気になる記事を見つけました。
http://www.nabble.com/noncopyable-EBO-problem--p10899161.html
この記事では、noncopyable は EBO(Empty Base Optimization: 空の基底クラスの最適化)が行われないケースがあると述べられています。そこで、この記事で最適化されないというケースを実際に次のように試してみました。
#include <iostream>
#include <boost/utility.hpp>
class A : boost::noncopyable {};
class B : boost::noncopyable { A a; };
using namespace std;
int main()
{
cout << "Size of A: " << sizeof(A) << endl;
cout << "Size of B: " << sizeof(B) << endl;
return 0;
}
これを g++ (GCC) 3.4.4 (cygwin) でコンパイルして実行すると、たしかに記事で述べられているようにsizeof(B)==2
が得られました。しかし、VC++ .NET 2003 で実行した結果はsizeof(B)==1
でした。というわけで、すくなくとも上のようなケースでもVC++ .NET 2003では最適化されるようです。ただ、このあたりはコンパイラのバージョンによっても変わってくるかもしれません(gcc4でどうなるか気になるところです)。
しかし、そもそも、上のクラス A のように空のクラスをnoncopyableにする必要性がクラス設計上、生じるかどうかちょっと疑問です(別にコピーできてもいいような気がします)。