如何理解虛表及其計算含虛函數的類的大小

在什麼狀況下系統會自動生成缺省(默認)的構造函數?ide

一、在類裏面有一個類類型的對象,這個類有本身的缺省構造函數(有缺省的參數,參數有缺省值)。函數

class Bspa

{3d

     B(int data)指針

     {  }對象

};不能合成blog

class B繼承

{圖片

     B(int data=0)get

     {  }

};會合成

class B

{

public:

    B(int data=0)

    {  }

};

class C:public B

{

public:

    C()

        :B(0)

    {  }

    B b;  //編譯器會自動合成

};

wKioL1cYizySzPe7AAAEzKZYT74235.png

二、類是虛擬繼承

class B

{

public:

    B()

    {}

};

class D:virtual public B

{

public:

    D()

    { }

    B b;

};

wKioL1cYi4DQ6hQFAAAFyW4Ryr4745.png

三、基類有缺省構造函數,子類沒有顯示定義本身的構造函數

class B

{

public:

    B(int data=0)

    {}

};

class D: public B

{

public:

};

wKiom1cYiv7Rp83dAAAE1JkXNHg716.png


四、有虛函數的類,系統自動生成缺省的構造函數來初始化虛指針

class B

{

public:

    virtual  void fun()

    {

        cout << "fun" << endl;

    }

};

wKiom1cYizXz8VDFAAAEeyrg3_Q065.png

前面是一些構造函數方面的總結,菜鳥一個寫的太爛,進來的先湊合着看,會不定時補充,有錯誤的地方還請多多指點

****************************************************************************************

虛函數:

class Base

{

public:

    virtual void FunTest()

    {

        cout << "Base::FunTest()" << endl;

    }

    virtual void FunTest1()

    {

        cout << "Base::FunTest1()" << endl;

    }

    virtual void FunTest2()

    {

        cout << "Base::FunTest2()" << endl;

    }

    virtual void FunTest3()

    {

        cout << "Base::FunTest3()" << endl;

    }

    virtual void FunTest4()

    {

        cout << "Base::FunTest4()" << endl;

    }

};

int main()

{

    Base b;

    system("pause");

    return 0;

}

    Base b;

009253E8  lea         ecx,[b]  

009253EB  call        Base::Base (0921226h)   

有call命令說明編譯器有合成缺省構造函數

wKioL1cYjVCCj6QWAAAX-esunM8894.png

取b的地址,b指向的那塊空間裏存放着另外一個地址,該地址指向的空間存放着虛表地址

wKiom1cYjKeT6MhgAAAG15Bnopg852.png

wKioL1cYjWqyYsLbAAAMCh6wrXg205.png

wKiom1cYjMLy2QiKAABRxxzPgMI347.png

wKiom1cYjMKQ8lkdAAAwFrykXRA871.png

虛指針指向虛表

虛表的順序和函數的聲明順序是同樣的

虛函數的大小:

***************************計算大小*********************************

class C

{

public:

char a;  //1

static char b;  //靜態成員在靜態區域,不在棧區,因此不算

void *p;    //指針佔4個字節

static int *c;   //靜態成員在靜態區域,不在棧區,因此不算

virtual void func1()

{}

virtual void func2() 

{}

//虛函數屬於同一類,故只須要一個這個指針指向虛函數表,

//佔用4個字節,就算有N個虛函數,也是4個字節

};


int main()

{

C c;

cout << sizeof(C) << endl;    //12

cout << sizeof(c.a) << endl;    //1  

cout << sizeof(c.b) << endl;   //1    類型的大小

cout << sizeof(c.c) << endl;    //4     類型的大小

cout << sizeof(c.p) << endl;    //4   

return 0;

}

相關文章
相關標籤/搜索