2

私たちが持っていると言う

Class A
{
   public:
   int _i;
   virtual int getI();
};
class B : public A
{  
   public:
   int _j;
   virtual int getI();
};

では、メモリ内のクラスのサイズがそのメンバーの合計であると仮定すると (つまり、パディングや実際に発生する可能性のあることを無視して)、B インスタンスのサイズはどれくらいになるでしょうか? sizeof(A) + sizeof(int) + sizeof(vptr) ですか? または、B インスタンスは個人的な A インスタンスに A vptr を保持しないので、sizeof(b) は sizeof(int) + sizeof(int) + sizeof(vptr) になりますか?

4

4 に答える 4

3

これは、コードを機能させるために実装が必要とするものです。2 * sizeof(int)type のオブジェクトにBは 2 つintの s (およびおそらく他のもの)が含まれているため、少なくとも であると言えます。典型的な実装ではABvptr を共有し、合計サイズは 2 つの int よりも 1 つのポインターだけ大きくなります (アラインメントのためのモジュロ パディングですが、ほとんどの実装では何もないと思います)。しかし、これは単なる典型的な実装です。あなたはそれを頼りにすることはできません。

于 2011-09-23T13:36:06.280 に答える
1

vtable の存在でさえ C++ 標準では指定されていないため、vtable の話は特定の実装に固有のものになります。これは実装の詳細です。

通常、オブジェクトは vtable へのポインタを 1 つだけ持ち、その vtable はそのタイプのすべてのオブジェクト間で共有されます。派生クラスには、基本クラスの各仮想関数と継承されなかった各新しい仮想関数のテーブルにポインターが含まれますが、これも静的テーブルであり、オブジェクトの一部ではありません。

実際に質問に答えるために、最も可能性の高い結果は sizeof(B) == sizeof(A::_i) + sizeof(B::_j) + sizeof(vptr) です。

于 2011-09-23T14:06:09.400 に答える
0

James Kanze の発言に加えて、(典型的な実装では) B の仮想テーブルの先頭に A の仮想テーブルが含まれることに言及する価値があるかもしれません。

例えば:

class A {
    virtual void x();
    virtual void y();
};

class B : A {
    virtual void y();
    virtual void z();
};

A の仮想テーブル:

  • 斧()
  • あ:はい()

B の仮想テーブル:

  • 斧()
  • B :y()
  • B:z()

そのため、B のインスタンスは 1 つの仮想テーブル ポインターだけで済むのです。

ところで、多重継承は物事をかなり複雑にし、オブジェクトごとに複数の仮想テーブル ポインターを導入する可能性があります。

これはすべて実装の詳細であり、それに依存するコードを書くべきではないことに常に留意してください。

于 2011-09-23T13:47:45.073 に答える
0

なぜあなたは知りたいのですか?プログラムでそれを使用する場合は、計算するよりも移植性の高い方法を探して、サイズを返す仮想関数を追加するか、ランタイムの型情報を使用して正しい型を取得してから、サイズを返します。

(投票するかコメントを追加すると、回答の装飾が始まります)

于 2011-09-23T13:53:57.013 に答える