虛函數揭祕

虛函數揭祕

虛函數是什麼?

​ 虛函數就是在類中定義的加了關鍵字virtual的函數,我們知道在類中定義普通函數,四大函數並不會影響類的大小。

那麼我們來看下在空類中定義一個虛函數會不會影響類的大小?

    #include<iostream>
    using namespace std;

    class Base{
    //	虛函數就是加了關鍵字的函數 
        virtual void func1(){
            cout<<"fun2 -----" <<endl;
        }
    };

    int main(){
        cout<< "size of base:" << sizeof(Base) << endl; 
    } 

在這裏插入圖片描述

我們可以看到上面的大小變成了8,那麼爲什麼變成8 了呢?編譯器幫我們做了什麼?

虛函數的原理

​ 對於一個類而言,在類中定義一個虛函數,那麼編譯器會幫我們生產一個虛函數指針。放到this指針指向的第一個元素位置,後面再跟類的成員。

    #include<iostream>
    using namespace std;

    class Base{
    //	虛函數就是加了關鍵字的函數 
        int a;
        virtual void func1(){
            cout<<"fun2 -----" <<endl;
        }
    };

    int main(){
        cout<< "size of base:" << sizeof(Base) << endl; 
    } 

​ 對於上面的類大小輸出爲16,虛函數指針佔8,int佔4個字節,同時對齊佔用了4個字節。
在這裏插入圖片描述

那麼如果我們在一個類中定義了多個虛函數呢?虛函數指針是一個? 還是多個呢?

在這裏插入圖片描述

事實證明多個虛函數也只會有一個虛函數指針。那麼虛函數指針是怎麼和真實的函數產生聯繫的呢?實際上編譯器維護了一張虛函數表。虛函數表裏面存放了函數的地址,函數地址也可以稱之爲函數指針。

如下圖:

在這裏插入圖片描述

我們可以通過指針來直接調用虛函數 指針是無比強大的

    #include<iostream>
    using namespace std;

    class Base{
    //	虛函數就是加了關鍵字的函數 
        int a;
        virtual void func1(){
            cout<<"fun1 -----" <<endl;
        }

        virtual void func2(){
            cout<<"fun2 -----" <<endl;
        }
    };
    typedef void (*func_ptr)() ; 
    int main(){

        cout<< "size of base:" << sizeof(Base) << endl; 
        Base b;
        Base *ptr = &b;

        long *virtual_ptr = (long *)ptr;
        cout << "首地址: "<< virtual_ptr <<" 虛函數表地址 "<< *virtual_ptr << endl;
        long address = *virtual_ptr;

        func_ptr v1 = (func_ptr)(*(long*)address);
        func_ptr v2 = (func_ptr)(*(((long*)address)+1));

        v1();
        v2();
    } 

​ 上面代碼執行效果:

在這裏插入圖片描述

多態實現的原理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章