【问题标题】:Private inheritance visibility/access in C++C++ 中的私有继承可见性/访问
【发布时间】:2020-02-11 06:35:38
【问题描述】:

为什么接口由于私有继承而在方法中具有特殊的可见性?

请注意,我的派生类中需要全局说明符 ::

我不明白为什么一个方法由于私有继承而继承了某种可见性。 Derived 类无法访问 Control 是完全合理的。但是为什么它也不能通过成员访问呢?

class Control
{
public:
    void ModifySomething();
};

class Base : private Control
{
private:
    virtual void Update( Control& i_control );
};

class Derived : public Base
{
private:
    // ----------↓↓
    void Update( ::Control& i_control ) override;
};

注意:我知道我们可以通过组合来解决这个问题。但我想知道为什么它在 C++ 中是这样定义的。我们可以打破 const-ness 还是什么?

【问题讨论】:

  • 您似乎在问多个不同的问题。你能编辑你的问题,让它提出一个明确的问题吗?
  • 你说的But why also through a member?是什么意思
  • @Brian 现在还好吗?
  • @appleapple 修复可读性

标签: c++ class inheritance access-control injected-class-name


【解决方案1】:

根据 C++ 17 标准(14.1 访问说明符)

5 [注意:在派生类中,基类名称的查找将 找到注入的类名而不是基类的名称 声明它的范围。注入的类名可能是 比其范围内的基类名称更不易访问 它被宣布。 ——尾注]

还有一个类似于你的代码sn-p的例子。

[示例:

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

—结束示例]

即派生类定义中私有基类的注入类名隐藏了命名空间中定义的基类名。这个注入的名字是私有的。因此派生类无法访问此私有注入名称。

【讨论】:

  • 这就是我一直在寻找的概念和解释:injected-class-name
【解决方案2】:

class Derived 无法访问class Base 中的任何private,因此它无法访问class ControlBase。但是,它可以直接访问Control,因为它与Derived 在同一个全局范围内声明。

作为@foreknownas_463035818 cmets,从DerivedControl 的路径有两条,但一条由于private 访问控制而被阻止,因此选择了另一条全局路径。

【讨论】:

  • 正确地说 Control 通过两个不同的路径在范围内,而编译器必须首选的一个被阻止,因为它是私有的?
  • 我不明白为什么这两条路径存在。为什么它在语言中是这样定义的?私有继承应该就像派生类不存在一样。但是,它确实存在,因为我需要指定全局范围。
  • 因为Control 在全局namespace 中,privately 继承它不会改变这一点。
猜你喜欢
  • 2012-01-05
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 2012-08-30
  • 1970-01-01
  • 2012-01-04
相关资源
最近更新 更多