1. 程式人生 > >匯編角度解釋一下繼承與多態

匯編角度解釋一下繼承與多態

偏移 mes alt info ring b- body climits turn

1 代碼

#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <climits>
#include <algorithm>
#include <math.h>
#include <utility>
using namespace std;

class A
{

  public:
    A()
        : a1(2)
    {
        int i = 0;
        ++i;
    }
    virtual int do1() { return 1; }
    virtual int do2() { return 2; }
    int a1;
};

class B : public A
{
  public:
    B()
        : b1(2)
    {
        int i = 0;
        ++i;
    }

    virtual int do1() { return 3; }
    int b1;
    int b2;
};

class C : public virtual A
{
  public:
    C()
        : c1(2)
    {
        int i = 0;
        ++i;
    }
    virtual int do1() { return 4; }
    int c1;
};

int main()
{
    A *a = new A;
    B *b = new B;
    C *c = new C;

    A *ab = b;
    b->do1();
    A *ac = c;
}

構造函數體中的代碼沒有意義只是為了解釋代碼執行的順序。

首先看:

技術分享圖片

匯編:

技術分享圖片

上面最後一個註釋錯了,rbx是申請的內存,構造函數沒有返回值,因此rbx直接賦值給指針a了。

然後看A:A()

技術分享圖片

(至於為什麽是:OFFSET FLAT:vtable for B+16 。抱歉不知道啊。查到的時候再補

緊接著看看 vtable for A 是什麽:

技術分享圖片

然後再看:

技術分享圖片

這裏A就算構造結束,還算是簡單。

看B的構造

技術分享圖片

匯編

技術分享圖片

可以非虛繼承就是在派生類的內存空間上依次調用基類的構造函數。基類的數據成員在派生類中依次擺放。並且派生類的數據成員的偏移在編譯階段就確定好了。

虛繼承

匯編角度解釋一下繼承與多態