为什么拥有私有基类的声明会导致无法访问类型名称? [英] Why does having a declaration of a private base class render a type name inaccessible?

查看:38
本文介绍了为什么拥有私有基类的声明会导致无法访问类型名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

令我惊讶的是,在下面的示例中,将Middle的基类声明为private使得该名称不能在后续派生中用作类型.

I am surprised that in the following example declaring Middle's base class private makes that name unavailable as a type in a subsequent derivation.

class Base {
public:
  Base(Base const& b) : i(b.i) {}

  int i;
};

class Middle : private Base {            //<<<<<<<<<<<
public:
  Middle(Base const* p) : Base(*p) {}
};

class Upper : public Middle {
public:
  Upper(Base const* p) : Middle(p) {}    //<<<<<<<<<<<
};

使用g ++(Debian 6.3.0-18 + deb9u1)6.3.0 20170516 ...如此编译

Compiling thusly with g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516...

g++ -std=c++11 privateBase.cpp

我得到以下诊断信息:

privateBase.cpp:15:9: error: ‘class Base Base::Base’ is inaccessible within this context
   Upper(Base const* p) : Middle(p) {}
         ^~~~
privateBase.cpp:1:12: note: declared here
 class Base {
            ^

很明显,在将Base用作Middle的基类的时候,其名称可以用作类型.我可以理解,当使用Base表示应为私有的基类存储时.但是,至少有一个私有基类的声明会导致类型名称无法访问,这至少是意外的.

Clearly at the point that Base was used as Middle's base class its name was available as a type. I can understand that when Base is used to denote base class storage that should be private. But having a declaration of a private base class render a type name inaccessible seems, at the very least, unexpected.

推荐答案

参见核心问题175 ,该问题甚至在[class.access.spec] p5中添加了一个说明这一点的示例:

This is intended; see core issue 175, which even added an example illustrating this in [class.access.spec]p5:

[注意:"在派生类中,将查找基类名称注入的类名,而不是基类的名称声明的范围.注入的类名可能更少可以访问的范围比基类在其作用域中的名称被宣布.— 尾注] [示例:

[ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. — end note ] [ Example:

class A { };
class B : private A { };
class C : public B {
  A* p;             // error: injected-class-name A is inaccessible
  ::A* q;           // OK
};

最终示例]


这不属于类名注入之间的交互(有关原理,请参见为什么会有注入的类名?),以及在C ++访问控制中应用名称查找之后而不是之前查找的事实.


This falls out of the interaction between class name injection (for rationale, see Why is there an injected class name?) and the fact that in C++ access control applies after name lookup, not before.

这篇关于为什么拥有私有基类的声明会导致无法访问类型名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆