C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++の空のクラスのオブジェクトサイズは1バイト?sizeofで確認する方法

C++では、メンバ変数を一切持たない「空のクラス」であっても、そのオブジェクト(インスタンス)のサイズは1バイトになります。一見不思議に感じますが、これには言語仕様上の明確な理由があります。ここでは、実際のコードでその挙動を確認してみましょう。

空のクラスのサイズを確認するサンプルコード

#include <bits/stdc++.h>
using namespace std;
class p1 {
    public:
    void first() {
        cout << "\nThe parent class p1 function is called.";
    }
};
class p2
{ };
int main() {
    cout << "The size of non-empty class p1 = " << sizeof(p1);
    cout << "\nThe size of empty class p2 = " << sizeof(p2);
    p2 p;
    cout << "\nThe size of object of empty class p2 = " << sizeof(p);
    p1 o;
    cout << "\nThe size of object of non-empty class p1 = " << sizeof(o);
    return 0;
}

実行結果

The size of non-empty class p1 = 1
The size of empty class p2 = 1
The size of object of empty class p2 = 1
The size of object of non-empty class p1 = 1

コードの解説

このプログラムでは、メンバ関数のみを持つクラスp1と、何も含まない空のクラスp2を定義しています。

class p2
{ };

続いて、sizeof演算子を使用して、各クラス自体のサイズと、そこから生成したオブジェクトのサイズを出力しています。

cout << "The size of non-empty class p1 : " << sizeof(p1);
cout << "\nThe size of empty class p2 : " << sizeof(p2);
p2 p;
cout << "\nThe size of object of empty class : " << sizeof(p);
p1 o;
cout << "\nThe size of object of non-empty class p1 : " << sizeof(o);

なぜ空のクラスでも1バイトになるのか?

C++の規格では、異なるオブジェクトは必ず異なるメモリアドレスを持つことが保証されています。もし空のクラスのサイズが0バイトだった場合、配列として複数のオブジェクトを作成した際に、複数のオブジェクトが同一アドレスを共有してしまう問題が発生します。

このため、コンパイラは空のクラスに対しても最小限の1バイトを割り当て、すべてのオブジェクトが一意のアドレスを持てるようにしています。また、メンバ関数だけを持つクラスp1のサイズも1バイトである点に注目してください。メンバ関数はオブジェクトごとに保持されるのではなく、すべてのオブジェクトで共有されるため、データメンバがなければサイズには影響しません。

  1. C#のObjectクラスとは?全クラスの基底クラスと主要メソッドを徹底解説

    C#におけるObjectクラスは、すべてのクラスの継承階層において最も上位に位置する基底クラス(ルートクラス)です。C#で定義されるあらゆる型は、明示的に指定しなくても自動的にObjectクラスを継承しており、そのためすべてのオブジェクトはObjectクラスが提供するメソッドを利用できます。Objectクラスの主なメソッド一覧Objectクラスには、以下のような重要なメソッドが用意されています。番号メソッドと説明1Equals(Object)指定されたオブジェクトが、現在のオブジェクトと等しいかどうかを判定します。2Equals(Object, Object)指定された2つのオブジェクトインス

  2. Java 9のCleanerクラスとは?finalize()の代替となる使い方を解説

    プログラムの実行中に生成されたオブジェクトは、ガベージコレクタ(GC)によって自動的に削除されます。オブジェクトがどのスレッドからも参照されておらず、JVMがそのオブジェクトへアクセスできないと判断した場合、そのオブジェクトはガベージコレクションの対象となります。 Objectクラスにはfinalize()メソッドが用意されており、GCがヒープからオブジェクトを削除しようとする前に自動的に呼び出される仕組みでした。しかしJava 9では、このfinalize()メソッドは非推奨(deprecated)となり、代わりに新しいクラスjava.lang.ref.Cleanerがガベージコレクション管