51

たとえば、Temp クラスがあるとします。

class Temp
{
    public:
        int function1(int foo) { return 1; }
        void function2(int bar) { foobar = bar; }

    private:
        int foobar;
};

クラス Temp のオブジェクトを作成するとき、必要なスペースの量をどのように計算し、メモリ内でどのように表現されるか (例: foobar の場合は 4 バイト | function1 の場合は 8 バイト | etc | )

4

11 に答える 11

75

一次近似では、オブジェクトのサイズは、その構成データ メンバーのサイズの合計です。これよりも小さくなることはありません。

より正確には、コンパイラには、データ メンバー間にパディング スペースを挿入して、各データ メンバーがプラットフォームのアライメント要件を満たすようにする権利があります。一部のプラットフォームはアラインメントに関して非常に厳密ですが、他のプラットフォーム (x86) はより寛容ですが、適切なアラインメントによりパフォーマンスが大幅に向上します。そのため、コンパイラの最適化設定でさえ、オブジェクトのサイズに影響を与える可能性があります。

継承と仮想関数により、さらに複雑になります。他の人が言ったように、クラス自体のメンバー関数は「オブジェクトごと」のスペースを占有しませんが、そのクラスのインターフェイスに仮想関数が存在することは、一般に、仮想テーブル、本質的に使用される関数ポインターのルックアップテーブルの存在を意味します実行時に呼び出す適切な関数実装を動的に解決します。仮想テーブル (vtbl) は、通常、各オブジェクトに格納されたポインターを介してアクセスされます。

派生クラス オブジェクトには、基本クラスのすべてのデータ メンバーも含まれます。

最後に、アクセス指定子 (public、private、protected) は、コンパイラにデータ メンバーのパッキングに関する一定の余裕を与えます。

簡単に言うと、 sizeof(myObj) または sizeof(MyClass) は常にオブジェクトの適切なサイズを教えてくれますが、その結果は常に簡単に予測できるとは限りません。

于 2009-06-02T03:27:17.027 に答える
21
sizeof(Temp)

サイズを出します。ほとんどの場合、それは 4 バイトであり (多くの仮定が与えられた場合)、それは int のみです。関数はオブジェクトごとに場所を取りません。関数は一度コンパイルされ、使用されるたびにコンパイラによってリンクされます。

オブジェクトのレイアウトが何であるかを正確に言うことは不可能ですが、標準ではオブジェクトのバイナリ表現を定義していません。

構造体のパディングなどのために、必ずしもデータ メンバーのバイトの合計ではないなど、バイナリ表現について注意すべき点がいくつかあります。

于 2009-06-02T03:16:07.830 に答える
8

実行時にオブジェクトがメモリ内でどのように表現されるかについて詳細な情報が必要な場合は、ABI ( Application Binary Interface ) 仕様を参照してください。コンパイラが実装する ABI を確認する必要があります。たとえば、GCC バージョン 3.2 以降はItanium C++ ABIを実装しています。

于 2009-06-02T03:29:27.880 に答える
7

メソッドは、インスタンス化された特定のオブジェクトではなく、クラスに属します。

仮想メソッドがない限り、オブジェクトのサイズは、非静的メンバーのサイズに、位置合わせのためのメンバー間のオプションのパディングを加えた合計になります。メンバーはメモリ内で順番に配置される可能性がありますが、仕様では、アクセス仕様が異なるセクション間の順序付けや、スーパークラスのレイアウトに対する順序付けは保証されていません。

仮想メソッドが存在する場合、vtableおよびその他の RTTI 情報用に追加のスペースが使用される場合があります。

ほとんどのプラットフォームでは、実行可能コードは実行可能ファイルまたはライブラリの読み取り専用.text(または同様の名前) セクションに配置され、どこにもコピーされません。class Temphas が methodの場合public: int function1(int)、メタデータには実際の実装用の関数 (コンパイラによってマングルされた名前が異なる場合があります)Tempへのポインターが含まれる場合がありますが、実行可能コードが埋め込まれていることは決してありません。_ZN4Temp9function1Ei

于 2009-06-02T03:30:36.867 に答える
4

メンバー関数は、特定のクラスのオブジェクトのサイズを考慮していません。オブジェクトのサイズはメンバー変数のみに依存します。仮想関数を含むクラスの場合、VPTR がオブジェクト レイアウトに追加されます。したがって、オブジェクトのサイズは、基本的にメンバー変数のサイズ + VPTR のサイズです。コンパイラは DWORD 境界でメンバー変数を見つけようとするため、これが当てはまらない場合があります。

于 2009-06-02T03:19:03.627 に答える
3

Microsoft Visual C++ を使用している場合、オブジェクトの実際の大きさを示すコンパイラ オプションが 1 つあります: /d1reportSingleClassLayout

Lavavej http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-3-of-nによるこのビデオを除いて、文書化されていません。

于 2011-11-02T13:36:46.680 に答える
0

これが役立つ場合があります。

さらに、クラス関数は他の関数と同じように表されます。C++ が関数に対して行う唯一の魔法は、関数名をマングルして、特定のクラス内の特定のパラメーター セットを持つ特定の関数を一意に識別することです。

于 2009-06-02T03:16:59.297 に答える