web-dev-qa-db-ja.com

関数を持つクラスのc ++ sizeof()

C++の質問があります。私は次のクラスを書きました:

class c
{
    int f(int x, int y){ return x; }
};

クラスcのsizeof()は「1」を返します。なぜ1が返されるのかよくわかりません。

何が起こっているのかをよりよく理解するために、別の関数を追加しました。

class c
{
     int f(int x, int y){ return x; }
     int g(int x, int y){ return x; }
};

今、以下は本当に私を混乱させました! sizeof(c)はまだ1(!?!?!?!)です。したがって、関数はクラスのサイズを変更しないと思いますが、なぜですか?なぜサイズが1なのですか?そしてそれはコンパイラ固有ですか?

ありがとう! :-)

22
TCS

クラスにはデータメンバーが含まれていないため、空です。標準では、すべてのクラスに少なくともサイズ1が必要であるため、それが得られます。 (メンバー関数は、物理的にクラスの「内部」ではなく、実際には、非表示の引数と名前空間およびアクセス制御を備えた単なる無料の関数です。)

43
Kerrek SB

サイズは1です。0にすることはできません。そうしないと、このタイプの2つのオブジェクトをアドレス指定できません(アドレスを区別できませんでした)。

11
BЈовић

メンバー関数は、基本的に通常の関数と同じであり、非表示のthisパラメーターを取得するだけです。したがって、特定のタイプの各インスタンスは、そのメンバー関数のコピーを持ち歩く必要はありません。コンパイラは通常の関数を追跡し、適切なthisパラメータを提供します。したがって、特定の型にいくつの関数があっても、そのサイズを変更する必要はありません。仮想関数などで複雑な継承を行うと、これはわずかに変化しますが、最終的には、関数の数がオブジェクトの最終的なサイズに影響を与えることはありません。

1バイトの初期サイズは、すべてのオブジェクトがある程度のスペースを占有する必要があるため、2つのオブジェクトが同じスペースを占有しないことを保証できます。配列について考えてみましょう..._a[5]_は*(a + 5)と同じであり、ポインタに追加すると、オブジェクトのサイズだけメモリアドレスが増加します。 sizeof(a)が_0_の場合、配列のすべての要素が同じアドレスに折りたたまれます。

あるスペースのオブジェクトタイプが標準で義務付けられていること...サイズが正確に1に等しいことは義務付けられていません。あなたの場合のsizeof(c)は23かもしれませんが、その理由はありません。

完全を期すために、サブオブジェクトのサイズをゼロにすることができます。空の基本最適化により、基本クラスが必要のない場合に実際のメモリを占有しないようにすることができます。したがって、正式にはDerivedBaseのインスタンスが隠されていても、sizeof(Base) == sizeof(Derived)はtrueである可能性があります。これは標準で許可されていますが、必須ではありません...たとえば、MSVCは状況によってはそれを使用しません。

5

1は1バイトを意味します。そしてその理由は、メソッドがオブジェクト内に格納されていないということです。それらは使用されますbyオブジェクトですが、それらには保存されません。クラスメンバーのみがオブジェクトに格納されます。プレーンなintメンバーなどを追加して、何が起こるかを確認してください。

1
Chris Eberle

sizeof(char)== 1は常に、charはバイトであり、sizeofはバイト数を返すためです。 (ただし、1バイトは必ずしも正確に8ビットである必要はありません。)

絶対に本当。したがって、「オクテット」という用語(であるものを、より一般的に使用される「バイト」という用語と正確に8ビット区別するため)。

詳細については、IEEE1541を参照してください。

http://en.wikipedia.org/wiki/IEEE_1541

0
paulsm4