use*_*015 25 c++ inheritance visual-studio-2013
class A {};
class B : private A {};
class C : private B
{
public:
class D : private A {}; // Error here
};
Run Code Online (Sandbox Code Playgroud)
此代码提供以下错误(在VS 2013中):
nested.cpp(8):错误C2247:'A'无法访问,因为'B'使用'private'继承'A'
如果我改变这样的定义,它会得到修复D:
class D : private ::A {};
Run Code Online (Sandbox Code Playgroud)
这是正确的行为,如果是这样,为什么?
起初我以为这是因为C私下继承B会隐藏基类.但如果我消除了"中间人"类B并且只使用它:
class A {};
class C : private A
{
public:
class D : private A {};
};
Run Code Online (Sandbox Code Playgroud)
错误消失了.
Aru*_*nmu 18
引用来自cppreference:
根据非限定名称查找的私有名称,可以通过限定名称查找来访问
考虑到这一点,让我们看看非限定名称查找如何适用于第一个示例:
class A {};
class B : private A {};
class C : private B
{
public:
class D : private A {}; // Error here
};
Run Code Online (Sandbox Code Playgroud)
A在范围内查找C.如果在那里定义,那就不会有问题.A是由它的基类(私有)类私有继承的B,因此会抛出编译器错误.Clang说:
note: constrained by private inheritance here:
class B : private A {}; 再次,根据它应该起作用的引用,如果你使用完全限定的名称,就像你已经显示的那样
class D : private ::A {};
Run Code Online (Sandbox Code Playgroud)
至于你的最后一个例子:
class A {};
class C : private A
{
public:
class D : private A {};
};
Run Code Online (Sandbox Code Playgroud)
它的工作原理是,名称查找适用于属于同一个类的所有名称.再次引用cppreference:
类的所有成员(成员函数体,成员对象的初始化器和整个嵌套类定义)都可以访问类可以访问的所有名称.
sky*_*ack 13
这是名称查找过程中的范围问题:
当您使用::A它时,它是一个完全限定的名称,因此您明确地引用了全局命名空间并A从那里获取.
当你继承A,C(让我说)看到A,您可以直接引用A名称中C使用不合格的名称.
当您从其范围继承B,C 查看 B和A私有时.它是私有的,但它存在.因为它A是一个不合格的名称,并且首先在该范围内查找,所以它恰好被发现并且无法访问,因此错误.
来自cppreference的示例:
class A { };
class B : private A { };
class C : public B {
A* p; // error: unqualified name lookup finds A as the private base of B
::A* q; // OK, qualified name lookup finds the namespace-level declaration
};
Run Code Online (Sandbox Code Playgroud)
使用私有继承,基类的public和protected成员将成为派生类的私有成员.
class B : private A {};
class C : private B
{
public:
class D : private A {}; // Error because all members of A is private to B so what
//would be the use of this private inheritance if you can't access any of A's member.
};
Run Code Online (Sandbox Code Playgroud)
而
class D :private ::A {};
Run Code Online (Sandbox Code Playgroud)
因为A的成员直接从全局命名空间中获取,所以可以D访问A公共成员和受保护成员.
| 归档时间: |
|
| 查看次数: |
1304 次 |
| 最近记录: |