编译器如何实现C++继承

How do compilers implement C++ inheritance?

本文关键字:C++ 继承 实现 何实现 编译器      更新时间:2023-10-16

C++支持继承。

但是它是如何在编译器中实现的呢?

编译器是否将所有实现从父级复制并粘贴到子级?

如果我们谈论的是这样的东西,则极度简化:

class A 
{
    public:
       int func1() { do something; }
       int func2() { do something; }
 };
class B : public A
{
    public:
       int func2() { do somethign else; }
};
B b;
b.func1();

那么编译器内部会发生这样的事情(记住,这是非常简化的,我相信真正的编译器代码会复杂得多):

 ... fname = "func1" from the source code ... 
 ... object = "b"; 
function fn;
while (!(fn = find_func(object, fname)))  
   object = parent_object(object);
if (fn)
  produce_call(fn); 
else
  print_error_not_found(fname);

如果我们谈论的是虚拟函数,那么编译器将生成一个表,其中包含相应虚拟函数的地址,并且该表是为每个类生成的,基于类似的原理"查找存在于这个类或其父类中的函数"

[在上面的文章中,我忽略了一个事实,即一个类可以有多个"父"类-这不会改变事情的工作方式,只是代码必须维护一个"同一级别的更多类"的列表或数组]

就像成员变量一样,基类会导致子对象嵌入派生类的所有实例中。基类的成员函数在派生类中不重复,而是在与基类对应的子对象上调用。

编译器知道此子对象相对于完整对象的位置,并将在指向派生对象和指向基对象的指针(或引用)之间有强制转换(可能是隐式的)的任何位置插入指针算术。这包括传递给基类型的成员函数的隐藏this指针参数。

虚拟继承有点棘手,因为根据派生类型的不同,偏移量可能会有所不同。在这种情况下,编译器需要将偏移量作为变量存储在类实例中,以便在运行时查找(就像指向虚拟成员函数的指针一样,可能需要另一层间接操作来节省空间)。