質問

2012-10-31 5 views
9

次のコードは、私のコンピュータ(Windowsの、VS2010)で質問

#include <iostream> 
using namespace std; 
class X{}; 
class Y: public virtual X{}; 
class Z: public virtual X{}; 
class A: public Y, public Z{}; 

int main() 
{ 
    cout<<sizeof(X)<<" "<<sizeof(Y)<<" "<<sizeof(Z)<<" "<<sizeof(A)<<endl; 
    return 0; 
} 

"C++オブジェクト・モデルの中に" 本からあり、出力は次のようになります。

Here're私の質問

1、はsizeof(X)= 1

本は言いますX型が2つのインスタンス、例えばxaとxbを生成するとき。コンパイルによってAにバイトが挿入され、xaとxbは異なるアドレスを持つことができます。私はその理由をあまり理解していない。

2、はsizeof(Y)= 4

仮想継承を使用することにより、我々は、追加の仮想ポインタを持っているのだろうか?私はこれが多形性の仮想ポインタと異なるかもしれないと思います。誰も私にYのメモリレイアウトを教えてもらえますか?

ありがとうございました!

+0

1つの質問につき1つの質問 –

+0

第1質問のためにチェックしてください:http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-空のクラスのオブジェクト?rq = 1 –

+1

私はあなたの主な質問は、Yは仮想多項式のクラスXから派生するために仮想継承を使用し、Y自体は非多形であるため、virutal継承自体がYはvテーブルを持っているので、そのサイズは4です。 – CashCow

答えて

6
  1. コンパイラ新しい文字であります32ビットシステムで4バイトのvptrテーブルを生成します
  2. Visual Studioを使用している場合は/d1reportAllClassLayoutプロパティ - > C/C++/Commandでオブジェクトレイアウトを生成します クラスYオブジェクトレイアウトはVisualメーカー:
  3. スタンリー・B・リップマンによる書籍「インサイドC++オブジェクトモデル」
  4. 非常によくこれを説明


     class Y size(4): 
      +--- 
      0  | {vbptr} 
      +--- 
      +--- (virtual base X) 
      +---
Y::[email protected]: 0 | 0 1 | 4 (Yd(Y+0)X)

vbi: class offset o.vbptr o.vbte fVtorDisp X 4 0 4 0
1

空のクラスのsizeofは、常に1を返します。空のクラスのダミーバイトは1つです。

Aだからのsizeof二つのポインタは8

YおよびZが両方ともにXの単一のエントリを持って保持する、すなわち仮想テーブルで2つのエントリ、Z

ための他のY ため いずれかを保持していますそれは、仮想だから、それは、異なるオブジェクトに

  • はsizeof(Y)= 4を生成することができるので、クラスが空である場合、その仮想テーブルは、従ってサイズが4

  • +0

    私はここでBとCと呼ばれるクラスは表示されません – CashCow

    1

    アンオブジェクトは、Yオブジェクト(この順序で)Zオブジェクトを含むだけであろう Xオブジェクト(YとZのポインタによって参照される) YとZの両方がXから実質的に継承されます。つまり、複数の継承が再生されると、1つのXオブジェクトだけが子クラス内でインスタンシエートされます。 Aはまだ2つのオブジェクト(1つのY、1つのZ)を持ち、sizeof = 8(sizeof = 4なので)です。しかし、YオブジェクトとYオブジェクトの両方のポインタは同じアドレスを指します。

    継承ツリーは次のようになります

    X 
    /\ 
    Y Z 
    \/
        A 
    
    0

    クラスは、少なくとも1バイトである-must-理由は、我々はXの配列を持っていると言うですもしそれらが0バイトであれば、&配列[1]は誰も期待しないであろう&配列[3]と同じアドレスを持ち、コードを壊すでしょう。それをチェックするコードを書く必要があり、どんな意味でも。

    Yは、単にあなたが手/コードで編集しない(あるいは少なくともいけない)ことができ、静的変数としてのvtableの(クラスや仮想関数への仮想ポインタを)考えることができます

    static void* virtual_ptr1 //note this is in virtual table and cannot be edited 
    

    だろう。それをコンパイラの予約された静的変数と考えてください

    +1

    私は理由説明sizeof(X)= 1 – Junjie