在编译器中实现受保护/私有继承

Implementation of protected / private inheritance in compiler

本文关键字:继承 受保护 编译器 实现      更新时间:2023-10-16

如果一个类派生自另一个类,例如

class B{};
class D : private B{};

那么我不能创建派生类对象,例如:-

B* ptr = new D;

如果我检查此代码与 D 类派生的汇编代码的汇编差异从公开的B类来看,我没有发现任何差异。

谁能确切地解释编译者如何以及在哪个阶段区分公共/受保护继承和私人继承。

编译器在分析代码时检查前端中的保护(公共/私有(。一旦它到达优化器和代码生成,它们就消失了。

private的意思是:"只能从班级内部或班级的朋友访问">

私有继承与公共继承相同;但是对于可以访问DB继承这一事实的代码存在限制。由于您可以使用私有继承与公共继承执行所有相同的操作(但仅限于有限的范围内(,因此两者以相同的方式实现是有意义的。

你声称你不能用B* ptr = new D;创建派生类,只有当你不在D的范围内时,才是正确的;例如,这有效:

class B{};
class D : private B{
    public:
    void makeB() {
        B* ptr = new D;
    }
};

编译器只是解析语言并确保你没有违反规则。

然后它继续生成一些机器代码(可能通过汇编语言(。

只要你没有违反C++规则,就可以自由地用机器代码进行实现。

所以在那个阶段私人/公共/受保护或其他什么都无关紧要。在链的更高位置,您受到保护

编译器检查访问,如果基类不可访问,则给出编译错误。 无需向可执行文件发出不同的代码。

在某些情况下,可能会发出不同的代码(例如,使用 RTTI、dynamic_cast 等进行运行时类型检查(,但在这种情况下您没有使用它。

偶然

B* ptr = new D;

可以在作为D的成员或friend的函数中执行。

你错了。您当然可以创建对象:

D* pd = new D;

但是,不能D对象强制转换为B类型,因为它具有"私有"作用域。
例如,您可以使用以下代码看到它:

D d;             // created successfully
B *pd = & d;     // forbidden
B &pb = d;       // forbidden

信息很明确:

'type cast' : conversion from 'D *' to 'B *' exists, but is inaccessible
'type cast' : conversion from 'D *' to 'B &' exists, but is inaccessible

这意味着对象D d存在,并且可以将其视为类型 B ,只是在此上下文中无法访问它。

这就是为什么您在程序集中看不到任何区别的原因:允许的操作在两种情况下看起来相同,不同的是不允许某些操作。