C/C++中空構造体、空配列、空クラスの役割

2141 ワード

1、sizeofとは何ですか.
  • オブジェクトタイプのサイズは、コンパイル時に直接決定されます.
  • sizeofは関数ではなく、オブジェクトタイプのサイズを返すマクロです.
  • は、オブジェクトまたはタイプが占めるメモリバイト数を返す役割を果たす.

  • 次の例で実行できます.
    int main()
    {
        int a = 12;
        int b[sizeof(a)];
        cout << sizeof(b)/sizeof(int) << endl;
        
        return 0; 
    }
  • スタック上で定義された配列は定数または定数式のみであり、変数を含まない.
  • スタック上で定義された配列は、変数を含むことができる.
  • int i = 10;
    //     
    int nums1[10];
    int nums2[10 + 2];
    //     
    int* nums3 = new int[i];

    2、オブジェクトのサイズ
    1つのクラスでは、ダミー関数、メンバー関数(静的および非静的を含む)、および静的データメンバーは、クラスオブジェクトの記憶領域を占有しません.
    オブジェクトのサイズ=vptr(虚関数テーブルへのポインタ)+すべての非静的データメンバーのサイズ+Aliginバイトサイズ(バイト整列)
    3、なぜsizeofの空のクラスの結果は1ですか?
    クラスはインスタンス化の過程で、ユニークなメモリアドレスを取得します.この目的を達成するために、コンパイラは空のクラスに隠しバイト(char)を追加し、インスタンス化されたメモリにユニークなアドレスを取得します.
    4、なぜ空のクラスを使うのですか.
    空のクラスは「汎用プログラミング」で、空のクラス(空の構造)の用途は非常に広いです.
    タイプ(通常は空のクラス)を使用して、異なるクラスのオブジェクトに対する属性を区別します.
    関数のリロード方法を使用することで、パラメータに空のクラスを追加して異なる関数を区別する方法として、コンパイル時に直接選択し、実行時に選択するのではなく、非常に効率的です.
    5、空の配列
    空の配列は構造体の中で空間を占めず、空の配列名はポインタ(ただし空間を占めない)であり、位置を指します.
  • 構造体において、ポインタは前のメンバーの終了後の最初の空間を指す.
  • 非構造体では、ポインタが指す内容は、前のオブジェクトのポインタの内容と同じである.

  • 次の例では、出力は8、すなわちcという空の配列は空間を占めない.
    struct Test
    {
        int a;
        char b;
        char c[0];
    };
    
    int main()
    {
        cout << sizeof(Test) << endl; //   8
        return 0;
    }
    

    6、クラス内の空の配列
    このとき出力は1.
    struct T
    {
        char c[0];
    };
    
    int main()
    {
        cout << sizeof(T) << endl; //   1
        return 0;
    }

    7、なぜ空の配列を使うのですか.
    質問:構造体にバッファを追加する場合は、どうすればいいですか?
  • は、一定の長さのbuffer配列メンバーを定義します.しかし、このようにbufferの大きさはロックされます.
  • はbufferポインタを定義し、コンストラクション関数でサイズが必要なbufferを動的に作成します.しかし、このスペースを特別に管理する必要があります.そうしないと、メモリの漏洩が発生しやすく、bufferポインタが1つのスペースを占めています.
  • この問題を解決するために空の配列を使用します:
  • このときsizeof(T)の値は8であり、buffer[0]は空間を占めない.申請スペースにbufferを付けるlen(バッファの長さ)は、構造体とバッファが一緒に申請されます.このような利点は、終了時にfreeを呼び出して構造体とバッファを一緒に解放し、独立した管理構造体とバッファを回避することである.
    sttuct  T
    {
       int a;
       int b;
       char buffer[0];
    }; 
    
    struct T* p=(T*)malloc(sizeof(T) +buffer_len);