【问题标题】:Base class is inaccessible error , why does private inheritance do this?基类不可访问错误,为什么私有继承会这样做?
【发布时间】:2019-09-28 13:20:56
【问题描述】:
class a
{
public:
    int var;
};

class b : a
{
};

int main()
{
    a* p = new b();

    return 0;
}

我知道它是由私有继承引起的,但我想知道为什么会这样?

【问题讨论】:

  • 它这样做是因为标准是这么说的。
  • 我认为我的问题被误解了,我不想访问类外的任何私有成员,或任何受保护的类层次结构外的成员,我只是想创建一个动态对象基类指针,它会引发错误
  • @AlexMercer - 没有被误解。虽然我不能代表其他人发言,但我可以说我对你的问题感到困惑的是你的问题是什么。该行为是预期的行为。该语言完全按照设计的方式运行。如果您对如何在语言框架内完成特定设计目标有疑问,而您所做的这种尝试不起作用,请提出该问题。事实上,没有人知道你在问什么问题。

标签: c++ class inheritance private-members


【解决方案1】:

这正是私有继承中“私有”的含义。 b 继承自 a 的事实是一个实现细节,从外部看不到。

我没有尝试访问类外部的任何私有成员,或任何受保护的外部类层次结构,我只是尝试使用基类指针创建一个动态对象,它会引发错误

您正在尝试访问从 b*a* 的转换,但您不能,因为从外部无法访问基类。私有继承更接近于组合而不是公共继承。您的示例可以重写为

class b {
      a a_instance;
};

b 的实现会略有不同(因为调用a 成员函数是通过a_instance 而不是this),但效果是一样的:我们编写ba而用户对此一无所知(又名private)。

【讨论】:

    【解决方案2】:

    您明确指定基类作为派生类的私有子对象继承。所以它在类定义之外是不可访问的。

    来自 C++ 17 标准(14.2 基类和基类成员的可访问性)

    1. ...如果一个类被声明为另一个类的基类,使用私有 访问说明符,公共和受保护成员 基类的可作为派生的私有成员访问 类。

    在此声明中

    a* p = new b();
    

    因为指针p 的静态类型是a *,所以试图访问b 类型的对象的a 类型的私有子对象。

    其实这个说法

    a* p = new b();
    

    与示例具有相同的语义

    class A
    {
    private:
        int x = 10;
    };
    
    A a;
    int *p = &a.x;
    

    如果允许,那么使用指针可以更改对象的私有子对象。

    【讨论】:

    • 当我创建一个静态对象(通过声明)时,这个错误不会出现,但是当我尝试创建一个动态对象时,会出现一个错误,说基类 a 不可访问
    • @AlexMercer 问题是使用 a * 类型的指针,您试图访问 b 类型对象的私有子对象。
    • @VladfromMoscow 那么private sub-objectobject of type b 在哪里?怎么知道you are trying to access it
    • @HelloEveryone 因为指针是通过私有子对象的地址初始化的。
    猜你喜欢
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 2018-09-04
    • 2013-10-23
    • 2013-09-09
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    相关资源
    最近更新 更多