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にする必要性がクラス設計上、生じるかどうかちょっと疑問です(別にコピーできてもいいような気がします)。