1

私はこのコードを持っています.2行がコメントアウトされていることに注意してください

#include <iostream>

class foo {
public:
    foo();
    int i;
};

class bar: foo {
public:
    bar();
    //int i;
};

foo::foo()
{
    i = 2;
}

bar::bar()
{
    i = 4;
}

int main()
{
    bar *b = new(bar);
    //std::cout << "bi = " << b->i << std::endl; /*line 28*/
    foo *f = (foo*) b;
    std::cout << "fi = " << f->i << std::endl;
}

2 行をコメントアウトすると、コードがコンパイルされ、出力は次のようになります。

fi = 4

2 行のコメントを外すと、コードがコンパイルされ、出力は次のようになります。

bi = 4

fi = 2

クラスバー内の i の宣言のみをコメントアウトすると、コンパイルは失敗します

var.cc: In function ‘int main()’:

var.cc:6:7: error: ‘int foo::i’ is inaccessible

var.cc:28:30: error: within this context

最初の 2 つのケースは理解できますが、このコンパイル エラーは理解できません。なぜですか

変数 "i" はバー コンストラクター内からアクセスできますが、バー ポインターからはアクセスできませんか?

4

3 に答える 3

3

プライベート継承では、基本クラスのすべてのメンバーがprivate派生クラスのメンバーになります。クラスのデフォルトの継承はprivate、何も指定しない場合であることに注意してください。

のメンバーとしてi機能するため、メンバー関数の外部からはアクセスできません。privatebarbar::bar()

よく読んだ:

アクセス指定子とは プライベート、プロテクト、またはパブリックで継承する必要がありますか?

于 2013-03-19T11:17:47.090 に答える
1

これは、プライベート継承を使用しているためです。

すべてのclassesprivateのデフォルトのアクセス修飾子です。これは、private特に明記しない限り、メンバーとベースが存在することを意味します。

ただし、structデフォルトは ですpublicclass実際、これが aと aの唯一の違いstructです。

したがって、 と書くclass bar: fooと、これは と同等class bar: private fooです。

class bar: public fooこの問題を解決するには、またはのいずれかを実行する必要がありstruct bar: fooます。この例ではどちらも同等です (デフォルトのアクセス修飾子を使用するメンバーがないため)。

于 2013-03-19T11:20:42.203 に答える
0

異なるクラスで同じ名前を持つ場合は、フィールドの名前スコープを直接指定する必要があります。

struct s1
{
  int i;
};

struct s2 : public s1
{
  int i;
};

int main()
{
  s2 v;

  v.s1::i = 1;
  v.s2::i = 2;

  std::cout << v.s1::i << v.s2::i << std::endl;

  return 0;
}

出力は12になります

于 2013-03-19T11:21:48.763 に答える