嵌套类继承的错误
Error with nested class inheritance
class A {};
class B : private A {};
class C : private B
{
public:
class D : private A {}; // Error here
};
此代码给出以下错误(在VS 2013中):
nested.cpp(8):错误c2247:'a''不访问,因为'b'使用'private'以从'a''''
继承
如果我更改D
的定义,则可以修复它:
class D : private ::A {};
这是正确的行为,如果是的话,为什么?
首先,我认为这是因为C
从B
私下继承,这将隐藏基本类。但是,如果我消除了"中间人"类B
,然后使用以下方式:
class A {};
class C : private A
{
public:
class D : private A {};
};
错误消失了。
引用 cppReference :
根据不合格的名称查找的名称,可能是 通过合格的名称查找
访问
考虑到这一点,让我们看看第一个示例的不合格名称查找将如何工作:
class A {};
class B : private A {};
class C : private B
{
public:
class D : private A {}; // Error here
};
-
A
在C
的范围内查找。如果在那里定义它,就没有问题。 - 它弄清楚
A
是由其基础(私有)类B
私下继承的,因此引发了编译器错误。Clang说:注意:在这里受私人继承约束:B类:私人A {};
再次,按照报价应起作用,如果您使用完全合格的名称,就像您显示的那样
class D : private ::A {};
,至于您的上一个示例:
class A {};
class C : private A
{
public:
class D : private A {};
};
它起作用是因为,该名称查找适用于同一类的所有名称。再次引用cppreference:
班级的所有成员(成员功能的主体,初始化器 成员对象和整个嵌套类定义) 对于可以访问的所有名称。
这是名称查找期间的范围问题:
-
当您使用
::A
时,这是一个完全合格的名称,因此您明确地参考了全局名称空间并从那里挑选A
。 -
当您从
A
继承时,C
(让我说)看到A
,您可以直接参考带有不合格名称的A
名称。 -
当您从
B
继承时,C
SEESB
和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
};
,由于私人继承,基地的公共和受保护成员成为派生阶级的私人成员。
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.
};
而
class D :private ::A {};
工作是因为A的成员直接从全球名称空间中获取,因此D
能够访问A
的公共和受保护的成员。
是理解的关键部分,在其他答案中没有明确阐明,这是以下内容:
班级的名称注入了类的范围。
也就是说,如果您有
class A {};
然后,您不仅可以用名称::A
,而且可以使用名称A::A
参考类A
。请注意,尽管描述了同一类,但它们是不是,就像它们在不同的范围中一样。
现在,当在A
的范围或直接或间接从A
派生的类范围内时,无限制的查找将找到A::A
而不是::A
(除非A::A
本身是由另一个名称隐藏的)。
此外,与其他某些语言不同,C 不会从无法访问它们的范围内的scopes中 hide 私有名称,而是仅使用访问说明符,仅将访问说明符为使用使用 name 。此外,这些权限与名称约束,而不是指定的实体(在这种情况下为类)。
因此,在您的代码中,在A
的不合格查找中,编译器找到隐藏名称::A
的名称C::B::A::A
,然后检查访问权限并在当前上下文中找到此名称是私有的,因为它是范围中的名称。C::B::A
的CC_34无法从C
中访问,因为A
是B
的私有基类。
类D:private :: a {};当您从B继承时,C看到B,A在其范围中是私人的。它是私人的,但存在。因为A是一个不合格的名称,并且首先在该范围中寻找它,所以它恰好被发现和无法访问,因此错误。
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 在 c++ 中拆分类和标头中的继承,错误
- enable_if继承的成员函数的名称查找错误
- C++模板类 - 继承调用错误的函数
- C++ 中的构造函数、继承、堆栈、堆、this-pointer 和段错误
- 为什么这个混合继承程序给出错误的输出?
- 使用多重继承时出现编译错误
- 多级继承错误 C2280:"atttempting to reference a deleted function"
- 相对于继承的构造函数,gcc 编译器是否还有一个错误?
- 从模板继承的 MSVC DLL 导出类会导致LNK2005已定义的错误
- 模板化类继承的子类定义中的错误
- C++错误LNK2005和不同项目文件的常规继承
- 错误:'int_type'未命名类型 - 如何继承 typedefs 和用法
- 在 soap_ssl_server_context(..) 中使用继承时 gsoap 中的分段错误
- C++中的继承,"...is an ambiguous base of ..."错误
- 与lambda一起使用虚拟继承在初始化列表中捕获此问题的GCC错误
- 收到未定义的引用错误 c++ 继承/多态性
- c++错误:继承转换无效
- 错误继承不能访问c++的方法