基类不可访问错误,为啥私有继承会这样做?

Posted

技术标签:

【中文标题】基类不可访问错误,为啥私有继承会这样做?【英文标题】: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;

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

【问题讨论】:

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

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

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

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

class b 
      a a_instance;
;

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

【讨论】:

【参考方案2】:

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

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

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

在此声明中

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 因为指针是通过私有子对象的地址初始化的。

以上是关于基类不可访问错误,为啥私有继承会这样做?的主要内容,如果未能解决你的问题,请参考以下文章

类的继承

c++类后面带一个:什么意思 class CAboutDlg : public CDialog//什么意思? public: CAboutDlg(); 求解释

5继承与派生2-访问控制

C++_练习—继承_公有继承

为啥具有私有构造函数的类不阻止从此类继承?如何控制哪些类可以从某个基类继承?

继承对基类私有数据成员的访问(在派生类中继承基类成员函数)