0

Base と Derived の 2 つのクラスがあるとします。

class Base
{
  private: 
int a;
}
class Derived:public Base
{
private:
int b;
 }
 int main()
{
 Derived d;
 cout<<sizeof(d);
  }

出力は 8 です。私の質問は、基本クラスのメンバー変数がプライベートであり、派生クラスがそれを継承できない場合、クラスのサイズを表示するときにデータ メンバーが含まれるのはなぜですか?

4

6 に答える 6

2

クラスを継承すると、クラス メモリ レイアウトは、新しいクラスで定義するすべてのものが後に続く、基本クラスを持つすべてのものになります。

A から継承するクラス B は、A に B クラスの新しい追加を加えたものと考えることができます。

于 2013-08-01T17:45:13.593 に答える
0

質問は実際には継承とは何の関係もありません。プライベート フィールドのみで、メソッドもフレンドも存在しないクラスがあります。実際には、フィールドにアクセスすることはできません。継承を含め、どこでも空のクラスと同じように扱われないのはなぜですか? ほとんどのコンパイラは、空の基底クラスを最適化して取り除きます。

標準で許可されているかどうかはわかりませんが、コンパイラを作成した場合、そのようなメンバーを最適化することはありません。おそらく、クラスは、おそらく別の言語で書かれた他のクラスとレイアウト互換である必要があります。ただし、そのようなフィールドについては警告を出します。

于 2013-08-01T17:55:03.043 に答える
0

base にプライベート メンバーを操作するメソッドがない場合でも、派生はメンバーにアクセスできませんが、例外は base のフレンド メンバーです。派生でアクセスする場合は、プライベート メンバーをプライベートではなくプロテクトにします。派生がパブリック継承ベースであることを確認してください。派生クラスはすべての基本クラスを継承していることに注意してください。ただし、プライベート メンバーを含め、ベースで操作するメソッドがない場合、プライベート メンバー var は、コンストラクターが適切ではない何かを行わない限り役に立ちません。

于 2013-08-01T17:48:43.007 に答える
0

ここでの実際の答えは、見た目よりも少しトリッキーです。

Derived最も派生したクラスと少なくとも 1 つの基本クラスの両方に非静的メンバーがあるため、標準レイアウト クラスではありません。したがって、レイアウトは完全に実装依存です。そのメンバーのオフセットやクラスのサイズについては何も予測できません。これは、 が直接続く構造体、その中にある構造体、または69105 バイトのパディングの後に続く構造体と同等である可能性があります。babab

したがって、コード内で a にアクセスできないことをコンパイラが検出できるという事実Derived::aは、ニシンです。

実際には、通常の標準レイアウトの方法で、次Derivedの構造体と同等に構築されないコンパイラを知りません…しかし、それはコンパイラを実装する最も簡単な方法であるためであり、言語が必要とするためではありませんそれ。ba

于 2013-08-01T17:59:18.853 に答える