可能性のある複製:
C++:空のクラスのオブジェクトのサイズは?
なぜ次の出力が1
?
#include <iostream>
class Test
{
};
int main()
{
std::cout << sizeof(Test);
return 0;
}
標準では、サイズ0のオブジェクト(およびそのクラス)は許可されません。これにより、2つの異なるオブジェクトが同じメモリアドレスを持つことが可能になるためです。そのため、空のクラスでも(少なくとも)1のサイズが必要です。
2つの異なるオブジェクトのアドレスが異なるようにするため。同じ理由で、「new」は常に個別のオブジェクトへのポインターを返します。
完全な答えは Stroustrup をご覧ください。
C++標準は、クラスのサイズが少なくとも1つであることを保証しています。 C++標準では、どのオブジェクトも別のオブジェクトと同じメモリアドレスを持つことはできません。これにはいくつかの理由があります。
new
が常に個別のメモリアドレスへのポインターを返すことを保証するため。
ゼロによる除算を避けるため。たとえば、ポインター演算(その多くはコンパイラーによって自動的に実行されます)は、sizeof(T)
による除算を伴います。
ただし、空の基本クラスが派生クラスのサイズに1を追加するという意味ではないことに注意してください。
struct Empty { };
struct Optimized : public Empty {
char c;
};
// sizeof(Optimized) == 1 with g++ 4.0.1
データメンバーやメンバー関数のないクラスは、このようなタイプのクラスは空のクラスと呼ばれます。空のクラスのオブジェクトのサイズは常に1バイトです。
その時点で任意のクラスのオブジェクトを作成すると、オブジェクトは常に3つの特性を取得します。
その時点で空のクラスのオブジェクトを作成すると、そのオブジェクトの状態は何もありません。そのオブジェクトの動作も何もありませんが、コンパイラはそのオブジェクトに一意のアドレスを割り当てます。コンピューターのメモリは常にバイトの形式で編成され、オブジェクトアドレスの場所で利用可能な最小メモリは1バイトです。これが、空のクラスのオブジェクトのサイズが1バイトである理由です。
モーリッツとペーターが言ったこと。
このコンテキストで、コンパイラが空の基本クラス最適化(EBCO)を実行できることに注意してください。
#include <iostream>
struct Foo {};
struct Bar : Foo {};
int main () {
std::cout << sizeof(Foo) << ',' << sizeof(Bar) << std::endl;
}
コンパイルして実行すると、おそらく「1,1」が出力されます。 EBCOの Vandevoorde/Josuttis 16.2 も参照してください。