11

これは一種の宿題の質問です。次のコードの場合、

#include <iostream>
using namespace std;

class A
{
public:
    virtual void f(){}
};

class B
{
public:
    virtual void f2(){}
};

class C: public A, public B
{
public: 
    virtual void f3(){}
};

class D: public C
{
public:
    virtual void f4(){}
};

int main()
{
    cout<<sizeof(D)<<endl;
}

出力は次のとおりです。8

誰かがそれが8バイトである方法を説明できますか?vtableの実装がコンパイラに依存している場合、インタビューでこの種の質問に答える必要がありますか?仮想基本クラスはどうですか?

編集:私は32ビットプラットフォームで作業しています。

4

4 に答える 4

16

もちろん、これは実装に依存します。そして、それはひどいインタビューの質問になるでしょう。優れたC++プログラマーはsizeof、正しいと信じて、コンパイラーにそれらのvtableのことを心配させることができます。

しかし、ここで起こっていることは、典型的なvtableベースの実装では、クラスCまたはのオブジェクトに2つのvtableが必要であるということDです。各基本クラスには独自のvtableが必要です。によって追加された新しい仮想メソッドは、1つの基本クラスからvtable形式を拡張することで処理できますが、とによって使用されるvtableをC組み合わせることはできません。DAB

疑似Cコードでは、D型の最も派生したオブジェクトが私の実装(g ++ 4.4.5 Linux x86)でどのように見えるかを次に示します。

void* D_vtable_part1[] = { (void*) 0, &D_typeinfo, &A::f1, &C::f3, &D::f4 };
void* D_vtable_part2[] = { (void*) -4, &D_typeinfo, &B::f2 };

struct D {
  void** vtable_A;
  void** vtable_B;
};

D d = { D_vtable_part1 + 1, D_vtable_part2 + 1 };
于 2011-01-22T05:40:51.200 に答える
4

この質問でクラス A のサイズを取得しようとすると、A には仮想関数が 1 つしかなく、その __vptr が「4」バイトになるため、答えは「4」になります。

同様に、クラス B のサイズを取得しようとすると、B にも仮想関数が 1 つしかなく、その __vptr が「4」バイトになるため、答えは「4」になります。

しかし、クラス C はクラス A と B の両方を継承しており、C 自体が仮想関数を持っています。そのため、C は 2 つの __vptr ポインターを受け取り、独自の仮想関数に対して C は継承された __vptr を使用します。クラス C のサイズを取得しようとすると、C には 2 つの仮想ポインターがあるため、答えは '8' になります。

最後に、クラス D はクラス C を継承しているため、D は継承された __vptr を独自の仮想関数に使用します。クラス C には sizeof '8' バイトがあるため、sizeof D は応答 '8' バイトを返します。

于 2012-08-31T08:28:10.477 に答える
1

漠然としていることを許してください、しかしあなたはそれが本質的に宿題であると言っています。

他のクラスに対してsizeof()が返すものを確認してください。答えは、コンパイラーと、32ビット環境か64ビット環境かによって異なります。

幸せな探偵!

于 2011-01-22T05:26:45.290 に答える
-2

オブジェクトのサイズは、オブジェクトが持つメソッドの数や、それらのメソッドが仮想であるかどうかとは関係ありませんオブジェクトのサイズは、そのメンバー変数によってのみ決定されます。

なぜ8バイトのサイズになるのか正確にはわかりません。クラスにはデータメンバーがないため、C ++コンパイラは原則として、スペースをまったく占有しないクラスを生成できます[1]。vtblへのポインターと、場合によってはパディングを提供するために必要な最小バイト数は8バイトだと思います。

[1]私は思います。スペックをチェックして、現時点でsizeof0を返すことができるかどうかを確認する時間はありません。

于 2011-01-22T05:28:02.077 に答える