【问题标题】:No use of base object allowed in private inheritance私有继承中不允许使用基对象
【发布时间】:2018-05-11 16:53:10
【问题描述】:

我正在使用 private 继承,我惊讶地发现在派生类中不允许使用任何 base 对象。

class A;
class B : private A;
class C : public B;

C::method_1()
{
    A* a; // Temporary "A" object for local computation
}

这与继承无关。我不想访问任何this->base method

此配置在 Visual Studio 中提供 C2247 错误(“'A' 不可访问,因为 'B' 使用 'private' 从 'A' 继承”)。

【问题讨论】:

标签: c++ oop inheritance


【解决方案1】:

改变这个:

A* a;

到这里:

::A* a;

由于C 继承自B,而B 继承自A,因此您需要范围解析运算符来解决问题。

::A 不是从包含类父级的本地范围开始,而是因为 :: 而开始查看全局范围。

来自Standard

11.1.5 访问说明符

在派生类中,查找基类名称会找到 注入类名而不是作用域中基类的名称 在其中宣布。注入的类名可能更少 比它所在范围内的基类的名称可访问 已声明。

【讨论】:

  • 在这种情况下,我并不真正理解范围运算符的含义,但它工作正常。谢谢!
  • @GuillaumeDespine:::A 不是从包含类父级的本地范围开始,而是因为 :: 而开始查看全局范围。
  • ISO : 11.1 访问说明符: [注意:在派生类中,基类名称的查找将找到注入的类名称,而不是声明它的范围内的基类名称。注入的类名可能比声明它的范围内的基类的名称更难访问。 —尾注] 有同样的例子
【解决方案2】:

ISO C++:11.1 访问说明符

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

以及标准中的示例:

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

N3797 Working Draft, Standard for Programming Language C++

【讨论】:

  • 如果这些类都在某个嵌套的命名空间中,这可能会很烦人
猜你喜欢
  • 2019-06-16
  • 2012-05-15
  • 1970-01-01
  • 2020-10-25
  • 2020-03-06
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多