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

时间:2017-02-09 06:46:48

标签: c++ compiler-construction

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

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

然后我无法创建派生类对象,如: -

B* ptr = new D;

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

任何人都可以确切地解释编译器如何以及在何种阶段区分公共/受保护和私有继承。

5 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

private表示:"只能在班级或班级朋友中访问"

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

如果您不在B* ptr = new D;范围内,那么您声称不能使用D制作派生类的说法是正确的。例如,这有效:

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

答案 2 :(得分:0)

编译器只解析语言并确保不破坏规则。

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

只要您没有违反C ++规则,就可以在机器代码中自由执行。

所以在那个阶段私人/公共/受保护或无关紧要。在您受到保护的链条上方

答案 3 :(得分:0)

如果基类不可访问,编译器将检查访问权限并提供编译错误。无需向可执行文件发出不同的代码。

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

顺便提及,

B* ptr = new D;

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

答案 4 :(得分:0)

你错了。你肯定可以创建对象:

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 ,在此上下文中无法访问它。

这就是为什么你没有看到汇编的任何差异:允许的操作,在两种情况下都看起来相同,不同的是某些操作不允许