如何在内存级别实现继承?

Moe*_*oeb 11 c++ memory inheritance implementation

假设我有

class A           { public: void print(){cout<<"A"; }};
class B: public A { public: void print(){cout<<"B"; }};
class C: public A {                                  };
Run Code Online (Sandbox Code Playgroud)

如何在内存级别实现继承?

Cprint()代码复制到自身还是有一个指向它的指针,它指向A代码的某个部分?

当我们覆盖先前的定义时,例如在B(在内存级别),同样的事情是如何发生的?

Max*_*ert 7

允许编译器实现它,但是他们选择.但他们通常遵循CFront的旧实施.

对于没有继承的类/对象

考虑:

#include <iostream>

class A {
    void foo()
    {
        std::cout << "foo\n";
    }

    static int bar()
    {
        return 42;
    }
};

A a;
a.foo();
A::bar();
Run Code Online (Sandbox Code Playgroud)

编译器将最后三行更改为类似于:

struct A a = <compiler-generated constructor>;
A_foo(a); // the "a" parameter is the "this" pointer, there are not objects as far as
          // assembly code is concerned, instead member functions (i.e., methods) are
          // simply functions that take a hidden this pointer

A_bar();  // since bar() is static, there is no need to pass the this pointer
Run Code Online (Sandbox Code Playgroud)

曾几何时,我会猜到这是在A创建的每个对象中使用指针到函数来处理的.但是,这种方法意味着每个A对象都包含相同的信息(指向同一函数的指针),这会浪费大量空间.编译器很容易处理这些细节.

对于具有非虚拟继承的类/对象

当然,那不是你提出的问题.但是我们可以将它扩展到继承,这是你所期望的:

class B : public A {
    void blarg()
    {
        // who knows, something goes here
    }

    int bar()
    {
        return 5;
    }
};

B b;
b.blarg();
b.foo();
b.bar();
Run Code Online (Sandbox Code Playgroud)

编译器将最后四行转换为:

struct B b = <compiler-generated constructor>
B_blarg(b);
A_foo(b.A_portion_of_object);
B_bar(b);
Run Code Online (Sandbox Code Playgroud)

有关虚拟方法的说明

当你谈论virtual方法时,事情变得有点棘手.在这种情况下,每个类都会获得一个特定于类的指针到函数的数组,每个virtual函数都有一个这样的指针.该数组称为vtable("虚拟表"),每个创建的对象都有一个指向相关vtable的指针.调用virtual函数通过查找正确的函数在虚函数表调用解决.