How is inheritance implemented at the memory level?

前端 未结 5 1122
无人共我
无人共我 2021-02-13 15:36

Suppose I have

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


        
5条回答
  •  被撕碎了的回忆
    2021-02-13 16:22

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

    For classes/objects without inheritance

    Consider:

    #include 
    
    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 = ;
    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
    

    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.

    For classes/objects with non-virtual inheritance

    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 = 
    B_blarg(b);
    A_foo(b.A_portion_of_object);
    B_bar(b);
    

    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.

提交回复
热议问题