如果编译下面的代码会失败,说明 B 类在用作成员函数 func 的参数的情况下是不可访问的。为什么是这样?
注意:如果 D2 没有从 D1 继承,那么错误就会消失,所以从 D2 继承的某种方式使 B 无法访问。
namespace myns {
class B {};
}
using namespace myns;
class D1 : B {};
class D2 : D1 {
void func(B b) {}
};
如果编译下面的代码会失败,说明 B 类在用作成员函数 func 的参数的情况下是不可访问的。为什么是这样?
注意:如果 D2 没有从 D1 继承,那么错误就会消失,所以从 D2 继承的某种方式使 B 无法访问。
namespace myns {
class B {};
}
using namespace myns;
class D1 : B {};
class D2 : D1 {
void func(B b) {}
};
名称查找发现D2::D1::B
,不是myns::B
。在名称查找之后,执行访问检查,并发现它D2::D1::B
是私有的。
B
命名空间是一条红鲱鱼:如果在全局命名空间中定义,则会观察到完全相同的结果。
您需要添加::
运算符。查找正在查找注入的类名而不是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
};
继承类/结构时的默认访问说明符是“private”,所以你的问题是:
class D1 : B {};
class D2 : D1 {};
添加关键字“public”,瞧。
namespace myns {
class B {};
}
using namespace myns;
class D1 : public B {};
class D2 : public D1 {
void func(B b) {}
};
int main() {
D2 d();
}