【问题标题】:The direct base class of private inheritance prevents the derived class from defining the object of the indirect base class私有继承的直接基类防止派生类定义间接基类的对象
【发布时间】:2021-01-07 09:36:10
【问题描述】:

喜欢这段代码

class Try
{
public:
    Try() = default;
    int i = 0;
};

class B1 : private Try
{
public:
    B1() = default;
    using Try::Try();
    using Try::i;
};

class C1 : public B1
{
public:
    Try a; //tell me:'Try' is a private member of 'Try'
    
    void print()
    {std::cout << i << std::endl;}
    //Access to this I is allowed;
};

Try a 是一个本地对象,不是 C1 的一部分,为什么会出错?

只要是私有继承的直接基类,就不能在其派生类中定义间接基类对象吗?是因为无法使用构造函数还是其他原因?

【问题讨论】:

  • 能否请您逐字发布完整的错误消息?

标签: c++ private-inheritance


【解决方案1】:

Try a 是一个本地对象,不是 C1 的一部分,为什么会出错?

通过在类C1 的上下文中写入Try a;,名称查找通常总是从本地范围扫描到全局范围。因此,第一个匹配项将是 B1::Try,由于私有继承,C1 无法访问。

修复很简单,只需向编译器提示您“真正”的意思,即通过编写例如::Try a;.

【讨论】:

  • 我了解到 c1 的类属于本地作用域。我还是不明白为什么本地动作不能定义对象?是因为私有继承吗?
  • @Nater 是的,您“通过镜头”访问B1Try,因为B1 是编译器查找名称Try 的下一个上下文,这不是在C1 中可用。但是,B1::Try 确实存在(由于继承),但是对于C1 是不可访问的(因为继承是私有的),所以从B1 之外,断言B1 派生自是无效的Try。编译器并不关心B1::Try 是否可访问,它会找到一个有效的名称并停止搜索另一个Try。这就是为什么您必须通过::Try 访问全局级别的Try 以提供提示。
  • 我有点理解,但我还有一个疑问:只要是私有继承,是不是就不能在其派生类中定义间接基类的对象?虽然直接基类的构造函数声明为public,但我在代码中做了一些改动
  • @Nater 不,这不是不可能的。正如我已经写过的,如果您通过::Try a; 访问它,您可以在私有继承到位时定义一个间接基类类型的对象。通过使构造函数可访问,您仍然无法使用B1::Try,因为从访问控制的角度来看,禁止任何继承假设(由于私有性)。
  • @Nater - 不 - 正如这个答案所说 - 私有继承不会阻止使用基类的实例作为派生类的成员。在C1 的上下文中,必须确保正确命名成员的类型(即,将成员指定为::Try a 而不是Try a)。在您的示例中,::TryTry 的完全限定名称。
猜你喜欢
  • 1970-01-01
  • 2018-05-19
  • 2017-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 2012-02-10
  • 2012-12-10
相关资源
最近更新 更多