3

以下のコードをコンパイルすると、メンバー関数 func の引数として使用されているクラス B にアクセスできないと言って失敗します。どうしてこれなの?

注: D2 が D1 から継承されていない場合、エラーはなくなるため、何らかの理由で D2 からの継承によって B にアクセスできなくなります。

namespace myns {
  class B {};
}

using namespace myns;

class D1 : B {};

class D2 : D1 {
  void func(B b) {}
};
4

3 に答える 3

5

名前検索ではD2::D1::Bではなくが見つかりmyns::Bました。名前検索後、アクセスチェックを行い、D2::D1::B非公開であることを発見。

名前空間は厄介者です: がBグローバル名前空間で定義されている場合、まったく同じ結果が観察されます。

于 2013-09-05T03:31:58.417 に答える
4

::オペレーターを追加する必要があります。ルックアップは、の代わりに注入されたクラス名を見つけていmyns::Bます。

class D2 : D1 {
  void func(::B b) {}
};

11.1p5

5 [ 注: 派生クラスでは、基本クラス名のルックアップは、それが宣言されたスコープ内の基本クラスの名前ではなく、注入されたクラス名を見つけます。注入されたクラス名は、それが宣言されたスコープ内の基本クラスの名前よりもアクセスしにくい場合があります。—終わりのメモ] [例:

class A { };
class B : private A { };
class C : public B {
  A *p; // error: injected-class-name A is inaccessible
  ::A *q; // OK
};
于 2013-09-05T03:31:47.120 に答える
0

クラス/構造体を継承するときのデフォルトのアクセス指定子は「プライベート」であるため、問題は次のとおりです。

class D1 : B {};
class D2 : D1 {};

キーワード「public」を追加すると出来上がりです。

http://ideone.com/T5RpUM

namespace myns {
  class B {};
}

using namespace myns;

class D1 : public B {};

class D2 : public D1 {
  void func(B b) {}
};

int main() {
    D2 d();
}
于 2013-09-05T05:28:14.850 に答える