如何在内存级别实现继承? [英] How is inheritance implemented at the memory level?

查看:76
本文介绍了如何在内存级别实现继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有

class A           { public: void print(){cout<<"A"; }};
class B: public A { public: void print(){cout<<"B"; }};
class C: public A {                                  };

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

How is inheritance implemented at the memory level?

C 复制 print()代码到自身还是有指向它的指针在 A 代码的一部分?

Does C copy print() code to itself or does it have a pointer to the it that points somewhere in A part of the code?

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

How does the same thing happen when we override the previous definition, for example in B (at the memory level)?

推荐答案

允许编译器然而他们选择实施这个。但它们通常遵循CFront的旧实现。

Compilers are allowed to implement this however they choose. But they generally follow CFront's old implementation.

考虑:

#include <iostream>

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

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

A a;
a.foo();
A::bar();

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

The compiler changes those last three lines into something similar to:

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

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

Once upon a time I would have guessed that this was handled with pointers-to-functions in each A object created. However, that approach would mean that every A object would contain identical information (pointer to the same function) which would waste a lot of space. It's easy enough for the compiler to take care of these details.

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

Of course, that wasn't really what you asked. But we can extend this to inheritance, and it's what you'd expect:

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

    int bar()
    {
        return 5;
    }
};

B b;
b.blarg();
b.foo();
b.bar();

编译器将最后四行变为:

The compiler turns the last four lines into something like:

struct B b = <compiler-generated constructor>
B_blarg(b);
A_foo(b.A_portion_of_object);
B_bar(b);



关于虚拟方法的说明



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

Notes on virtual methods

Things get a little trickier when you talk about virtual methods. In that case, each class gets a class-specific array of pointers-to-functions, one such pointer for each virtual function. This array is called the vtable ("virtual table"), and each object created has a pointer to the relevant vtable. Calls to virtual functions are resolved by looking up the correct function to call in the vtable.

这篇关于如何在内存级别实现继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆