2009-05-11 1 views
0

C++では問題が簡単です。C++ RTTI継承によりクラスサイズが増加する

私は実装の一部としてもう一方を含む2つのクラスを持っています。

struct A 
{ 
    void do_something() 
    { 
    }; 
}; 

struct B 
{ 
    A obj_A; 
    void hello_world() 
    { 
    }; 
}; 

今問題は、私ははsizeof(B)とタイプBのAのオブジェクトを実行するとき、AはBの一部である場合、構造Bは、1バイト大きい100%だけ唯一の非バーチャルを含むしようとしていることです(仮想テーブルは必要ありません)、タイプIDチェックの必要はありません。 Bから不要なバイトを完全に削除する方法はありますか(コンパイラ・ディレクティブのような)?

私は、余分なバイトがAの名前 "A"にchar *を追加したコンパイラだと仮定することができますが、それ以外のアイデアは役に立ちます。

+0

(それは我々がオペレータ&を使用するときに異なるアドレスを持つべきである)0にすることはできません'g ++ -fno-rtti'でコンパイルしてRTTIを無効にします。問題が解決しない場合は、問題を示す完全なC++ソースファイルを提供してください。 – pts

+1

FWIW:私はsizeof(B)== 1があるたびに、RTTIを有効または無効にしてobj_Aメンバーの有無にかかわらずg ++(バージョン4.2.4)でコードをコンパイルしようとしました。あなたの質問から。 –

答えて

2

残念ながら、コンパイラは言及していません。

とにかく、あなたが投稿するコードでは、クラスAは「空の基底クラス最適化」の候補です。これは、メンバー変数を持たない基本クラスをバイトなしで最適化できるというC++標準の一部です。

Bは、少なくとも1つのメンバ(obj_A)を含んでいるので、C++標準で領域を占有する必要があります。

do_something()を呼び出すことによって、Aのメンバー関数にB内から直接アクセスできます。魔法は必要ありません。オブジェクトの各部分が「アドレス可能」でなければなりません、ので

+0

クラスAは実際に基本クラスと見なされますか? –

+0

はい、リーフクラスでもあります –

+0

Bの基本クラスではなく、基本クラスである可能性があります。 – Ari

4

はsizeof(A)は、あなたのコンパイラをg ++、しようとした場合

struct A 
{ 
}; 

struct B 
{ 
    A m_a1; 
    A m_a2; 
}; 

void test() 
{ 
    B b; 
    A* pa1 = &b.m_a1; 
    A* pa2 = &b.m_a2; 

    // "pa1" need to be different from "pa2" 
} 
+0

+1そうです。また、クラスの新しいものは、削除の使用が適切に機能するように別のアドレスを返す必要があります。 C++の理由クラスはsize = 0を持つことができません。これとは別に、オブジェクトをメモリ語境界に揃えるためにコンパイラが追加できるパディングの側面があります。 – Abhay