C ++ 11、§9/ 7:
標準レイアウトクラスは、次のようなクラスです。
- タイプnon-standard-layoutクラス(またはそのようなタイプの配列)または参照の非静的データメンバーはありません。
- 仮想関数も仮想基本クラスもありません。
- すべての非静的データメンバーに対して同じアクセス制御があり、
- 非標準レイアウトの基本クラスはありません。
- 最も派生したクラスに非静的データメンバーがなく、非静的データメンバーを持つ基本クラスが多くても1つないか、非静的データメンバーを持つ基本クラスがない。
- 最初の非静的データメンバーと同じタイプの基本クラスはありません。
では、標準レイアウトのクラスをコピーできないようにする方法はありますか?はいの場合、どのように?
boost :: noncopyableからプライベートに継承すると、コピーコンストラクターがプライベートになります(したがって、標準のレイアウトではないため)。boost :: noncopyableの実装は次のようになります:
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
};
プライベートセクションのため、標準のレイアウトクラスではありません。また、プライベート継承が標準のレイアウトルールに違反するかどうかも確認します。
#include <boost/noncopyable.hpp>
#include <iostream>
const int N = 50;
struct A
{
int data[N];
};
struct B : private boost::noncopyable
{
int data[N];
};
struct C
{
A data[10];
};
struct D : private boost::noncopyable
{
B data[10];
};
int main() {
std::cout<<sizeof(A)<<std::endl;
std::cout<<sizeof(B)<<std::endl;
std::cout<<sizeof(C)<<std::endl;
std::cout<<sizeof(D)<<std::endl;
}
出力は次のとおりです。
200
200
2000
2004
上記の例は、からプライベートに継承boost::noncopyable
すると、クラスが標準レイアウトに準拠しないように変更されることを示しています。これがg++のバグ(私はg ++ 4.6.1を使用しています)なのか、それとも標準に違反しているのかわかりません。