3

.

ここで私は空のベースの最適化について議論していましたが、MSaltersは次のような興味深いコメントを残しました。

sizeof(Class)==0、空であろうとなかろうと、どのクラスも持つことはできません。しかし、空の基本クラスのサブオブジェクトのサイズについて具体的に話しています。 独自の vtable も vtable ポインターも必要ありません。オフセット 0 にある vtable ポインターの一般的なレイアウトを想定します。これにより、サイズがゼロの基本クラスのサブオブジェクトがその vtable ポインターを派生クラスと共有することになります。問題ありません。いずれにせよ、それらは同一である必要があります。それが仮想関数のポイントです。

私の質問は具体的には次のとおりです。空のクラスを基本クラスとして使用すると、コンパイラが最適化される場合とそうでない場合があります。それが実際に何をするかをどのように判断しますか?

一般に、基本クラスのサブオブジェクトのサイズを知るにはどうすればよいでしょうか? ベースとして使用するかどうかに関係なく、ベース サブオブジェクトのサイズは同じですか? コンパイラは空の基本クラスのみで最適化しますか?

.

4

3 に答える 3

4

良い答え。

ところで、MS VC++ および G++ コンパイラは、学習用にクラス レイアウトをダンプできます。

VC++で実行するだけcl.exe /c /d1reportAllClassLayout <source>.cpp

これは、1990 年に私が書いたクラスと vtable レイアウト ダンプ コードを使用して、適切なレイアウト オブジェクト、vtables、vbtables などをテストします。

C++ コンパイラがメモリ内でオブジェクトをレイアウトする方法をよりよく理解するには、http: //www.openrce.org/articles/files/jangrayhood.pdf と Stan Lippman の本 Inside the C++ Object Model をお楽しみください。

ハッピーハッキング!

于 2010-12-02T20:16:45.690 に答える
2

オブジェクトの最小サイズは 1 です。

class X {};
sizeof(X) >= 1

ただし、使用されていない場合、派生クラスはこのスペースにスペースを割り当てる必要はありません。

class Y : public X {};
sizeof(Y) >= 1

したがって、クラス X 自体が 1 バイトを占めますが、これは親クラスに変換されません。したがって、Y の観点からは、クラス X は 0 バイトを占有します。

したがって、ここでは、コンパイラが基本クラスを最適化したと言えます (ただし、技術的には何もしていません。オブジェクトのサイズがゼロではないという規則を適用する必要があるだけです)。

int main()
{
    std::cout << sizeof(X) << ":" << sizeof(Y) << "\n";
}

次の出力が生成されます。

> ./a.exe
1:1
>

クラスのサイズが 0 より大きくなければならない理由は、すべてのオブジェクトのアドレスが一意になるようにするためです。コンパイラがクラスのサイズを 0 にすることを許可した場合、複数の変数 (オブジェクト) がすべて同じメモリ アドレスを持つ (すべてのサイズが 0 であるため) 簡単なバグが発生する可能性があります。この潜在的な問題を回避するための簡単なルールは、すべてのオブジェクトのサイズがゼロ以外でなければならないということです。

概要:

size_of_type(X) = size_of_type(base) + sum(size_of_type(members)) + padding + (extra stuff like vtable pointer etc);


sizeof(<CLASS>) = min(1, size_of_type(<CLASS>))
于 2010-12-02T19:54:00.930 に答える
0

できません。実際のサイズはベースとなる情報と大きく異なる場合がありますsizeof()

EBO 以外の例として、仮想継承があります。

于 2010-12-02T19:32:59.523 に答える