22

C++ では、仮想関数を持たない基本クラスの継承に関連するオーバーヘッド (メモリ/CPU) はどれくらいですか? クラスメンバーのコピー&ペーストと同じくらい良いですか?

class a
{
public:
    void get();
protected:
    int _px;
}

class b : public a
{

}

と比べて

class a
{
public:
    void get();
protected:
    int _px;
}

class b
{
public:
    void get();
protected:
    int _px;

}
4

5 に答える 5

31

コピー アンド パストと比較して継承を使用すると、(パディングによる) わずかなメモリ オーバーヘッドが発生する可能性があります。次のクラス定義を考慮してください。

struct A
{
  int i;
  char c1;
};

struct B1 : A
{
  char c2;
};


struct B2
{
  int i;
  char c1;
  char c2;
};

sizeof(B1) はおそらく 12 ですが、sizeof(B2) はちょうど 8 かもしれません。これは、基本クラス A が個別に 8 バイトにパディングされ、次に B1 が再び 12 バイトにパディングされるためです。

于 2009-08-14T21:29:11.360 に答える
16

コンパイルには少し時間がかかりますが、実行時のオーバーヘッドは追加されません。オプティマイザの観点からは、非仮想メソッドはプロシージャと同じです。仮想メソッド テーブルからのオーバーヘッドなしで、メモリ アドレスのみを使用して呼び出すことができます。

于 2009-08-14T18:06:13.017 に答える
3

仮想継承を忘れた場合、基本クラスを持つことは、メモリとパフォーマンスの点で、同じクラスのメンバーを持つことと同等です。場合によってはさらに優れていることを除いて(たとえば、空のクラスのサイズは少なくとも1つですが、空の基本クラスがあるとオーバーヘッドが発生しないことがよくあります)。

于 2009-08-14T19:06:35.843 に答える
2

Derived* 型のオブジェクトを指す Base* 型のポインターがある場合は、おそらく仮想デストラクタが必要であり、元の前提は適用されなくなります。派生クラスに空のデストラクタがあり、メンバがないか、すべてが POD 型である場合、仮想デストラクタがなくても問題ありませんが、通常は安全にプレイして、最初から仮想にすることをお勧めします。

コンパイラは、各非仮想メンバー関数を実装するコードへの直接呼び出しを生成するため、オーバーヘッドはありません。

于 2009-08-14T19:14:31.507 に答える
1

実際には、基本クラスによってメモリが増加しただけです。詳細については、C++ FAQ を参照してください

于 2009-08-14T18:05:20.350 に答える