虛函數表是在編譯的時候還是運行的時候產生的


引入:這段時間一直在思考虛函數表的問題,同時也想知道虛函數表是在什么時候產生的

本人是在VS2010的環境下,如有錯誤歡迎指出,謝謝。

觀察代碼

#include<stdio.h>
#include<iostream>
class A{
public:A();
       virtual~A();
        void fun1(){
           printf("123");
       }
};
A::A(){
    printf("new A\n");
}
A::~A(){
    printf("Delete class A\n");
}

class B : public A
{
public:B();
       ~B();
       void fun2(){
           printf("123456");
       }
};

B::B(){
    printf("new B\n");
}
B::~B(){
    printf("Delete class B\n");
}    

class C : public B
{
public:C();
       ~C();
       void fun2(){
           printf("123456");
       }
};

C::C(){
    printf("new C\n");
}
C::~C(){
    printf("Delete class C\n");
}   


int main(){
    A *a=new A;
    //A *a=new C;
    delete a;
    getchar();
    return 0;
}

如果虛函數表是在運行的時候產生的話,那么這個代碼的話運行到A *a=new A的時候應該會在內存中產生與類A有關的虛函數表,讓我們觀察下虛函數表的情況:

我們發現這里有A的虛函數表,還有B的虛函數表,在觀察下還會發下C的虛函數表。

思考下為什么要怎么設計?

其實可以這樣理解,其實不管有多少類的對象,虛函數表就這么固定的幾個,是與類的種類個數相同的(所以說相同類所有對象共享的虛函數表),因為是固定的東西,那么在編譯的時候產生就可以了,   而多態的實現是通過對象中的vptr指針指向不同的虛函數表實現的,在運行的時候指針指向是可以有變化的,所以需要在程序運行的時候變化!

#include<stdio.h>
#include<iostream>
class A{
public:A();
       virtual~A();
        void fun1(){
           printf("123");
       }
};
A::A(){
    printf("new A\n");
}
A::~A(){
    printf("Delete class A\n");
}

class B : public A
{
public:B();
       ~B();
       void fun2(){
           printf("123456");
       }
};

B::B(){
    printf("new B\n");
}
B::~B(){
    printf("Delete class B\n");
}    

class C : public B
{
public:C();
       ~C();
       void fun2(){
           printf("123456");
       }
};

C::C(){
    printf("new C\n");
}
C::~C(){
    printf("Delete class C\n");
}   


int main(){
    
    C tempc;
    B tempb;
    A tempa;
    A *a=&tempc;//指針A在運行是變化,里面相應的虛函數指針也在運行時變化
    a=&tempb;
    a=&tempa;

    getchar();
    return 0;
}

總結:虛函數表在編譯的時候就確定了,而類對象的虛函數指針vptr是在運行階段確定的,這是實現多態的關鍵!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM