编译器中保护/私有继承的实现
Implementation of protected / private inheritance in compiler
如果 class 派生自另一个 class,例如
class B{};
class D : private B{};
那么我无法创建派生的 class 对象,例如:-
B* ptr = new D;
如果我检查此代码与 class D 派生的汇编代码的汇编差异
来自 class B publically,我没有发现任何差异。
任何人都可以准确解释编译器如何以及在什么阶段区分 public / 受保护和私有继承。
编译器在解析您的代码时在前端检查保护 (public/private)。一旦进入优化器和代码生成,它们就消失了。
private
表示:"Can only be accessed from within the class or friends of the class"
私有继承与public继承相同;但是对于哪些代码可以访问 D
继承自 B
这一事实存在限制。因为你可以用私有继承做所有与 public 继承相同的事情(但仅限于有限的范围),所以两者以相同的方式实现是有道理的。
你声称你不能用B* ptr = new D;
派生类只有当你不在D
的范围内时才是正确的;例如,这有效:
class B{};
class D : private B{
public:
void makeB() {
B* ptr = new D;
}
};
编译器只是解析语言并确保您没有违反规则。
然后它继续生成一些机器代码(可能通过汇编语言)。
只要您没有违反 C++ 的规则,就可以自由地使用机器代码进行实现。
所以在那个阶段 private/public/protected 或其他什么都不重要。在更高的链条上,您受到了保护
编译器检查访问,如果基 class 不可访问,则给出编译错误。无需向可执行文件发出不同的代码。
有些情况下可能会发出不同的代码(例如,使用 RTTI、dynamic_cast
等进行运行时类型检查),但在这种情况下您没有使用它。
顺便说一句,
B* ptr = new D;
可以在作为 D
的成员或 friend
的函数中执行。
你错了。您当然可以创建对象:
D* pd = new D;
你不能,然而,cast一个D
对象到基础B
类型,因为它的 'private' 作用域。
例如,您可以使用以下代码查看它:
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
,只是不能在此上下文中访问它。
这就是为什么您在汇编中看不到任何差异的原因:允许的操作在两种情况下看起来都一样,不同的是某些操作不允许.
如果 class 派生自另一个 class,例如
class B{};
class D : private B{};
那么我无法创建派生的 class 对象,例如:-
B* ptr = new D;
如果我检查此代码与 class D 派生的汇编代码的汇编差异 来自 class B publically,我没有发现任何差异。
任何人都可以准确解释编译器如何以及在什么阶段区分 public / 受保护和私有继承。
编译器在解析您的代码时在前端检查保护 (public/private)。一旦进入优化器和代码生成,它们就消失了。
private
表示:"Can only be accessed from within the class or friends of the class"
私有继承与public继承相同;但是对于哪些代码可以访问 D
继承自 B
这一事实存在限制。因为你可以用私有继承做所有与 public 继承相同的事情(但仅限于有限的范围),所以两者以相同的方式实现是有道理的。
你声称你不能用B* ptr = new D;
派生类只有当你不在D
的范围内时才是正确的;例如,这有效:
class B{};
class D : private B{
public:
void makeB() {
B* ptr = new D;
}
};
编译器只是解析语言并确保您没有违反规则。
然后它继续生成一些机器代码(可能通过汇编语言)。
只要您没有违反 C++ 的规则,就可以自由地使用机器代码进行实现。
所以在那个阶段 private/public/protected 或其他什么都不重要。在更高的链条上,您受到了保护
编译器检查访问,如果基 class 不可访问,则给出编译错误。无需向可执行文件发出不同的代码。
有些情况下可能会发出不同的代码(例如,使用 RTTI、dynamic_cast
等进行运行时类型检查),但在这种情况下您没有使用它。
顺便说一句,
B* ptr = new D;
可以在作为 D
的成员或 friend
的函数中执行。
你错了。您当然可以创建对象:
D* pd = new D;
你不能,然而,cast一个D
对象到基础B
类型,因为它的 'private' 作用域。
例如,您可以使用以下代码查看它:
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
,只是不能在此上下文中访问它。
这就是为什么您在汇编中看不到任何差异的原因:允许的操作在两种情况下看起来都一样,不同的是某些操作不允许.