C++ 支持继承。
但是它是如何在编译器中实现的呢?
编译器是否将所有实现从父级复制并粘贴到子级?
C++ 支持继承。
但是它是如何在编译器中实现的呢?
编译器是否将所有实现从父级复制并粘贴到子级?
就像成员变量一样,基类导致子对象嵌入到派生类的所有实例中。基类的成员函数不会为派生类复制,而是在与基类对应的这个子对象上调用它们。
编译器知道该子对象相对于完整对象的位置,并将在指向派生和基址的指针(或引用)之间存在强制转换(可能是隐式)的任何地方插入指针算术。这包括this
传递给基类型成员函数的隐藏指针参数。
虚拟继承有点棘手,因为偏移量可能会根据派生最多的类型而有所不同。在这种情况下,编译器需要将偏移量作为变量存储在类实例中,以便在运行时查找它(就像指向虚拟成员函数的指针一样,可能涉及另一层间接以节省空间)。
非常简化,如果我们谈论的是这样的事情:
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);
如果我们谈论的是虚函数,那么编译器会生成一个表,其中保存着各个虚函数的地址,并为每个类生成该表,基于类似的“查找该类中存在的函数”的原理或其父母之一)。
[在上面,我忽略了一个类可以有多个“父”类的事实——它不会改变事情的工作方式,只是代码必须维护一个“更多类”的列表或数组同一水平”]