1. 程式人生 > >C++建構函式中呼叫虛擬函式

C++建構函式中呼叫虛擬函式

談談關於建構函式中呼叫虛擬函式的情況,僅討論單繼承,不考慮虛擬繼承和多重繼承。 測試平臺:VS2013 + Win7X64 一個例子:
#include <stdlib.h>
#include <stdio.h>

class Base
{
private:
    int __data;

public:
    Base()
    {
        this->Func();
    }

public:
    virtual void Func()
    {
        printf("Base::Func");
    }
};

class Deri : public Base
{
public:
    Deri()
    {
        this->Func();
    }


public:
    virtual void Func()
    {
        printf("Deri::Func\n");
    }

};

int main(int argc, char** argv)
{
    Deri d;

    getchar();
    return 0;
}


輸出: Base::Func Deri::Func 首先討論下物件d的構造情況。 1 先構造基類部分,呼叫基類Base的建構函式,這個時候,派生類部分還沒有產生,這時候虛表應該是繫結基類的,自然呼叫的是Base::Func() 2 再構造派生類部分,這個時候,虛表發生變化,繫結在派生類上,呼叫Deri::Func() 雖然,在派生類中有過載Func這個函式,但是,在構造基類部分的時候,派生類的成員資料還沒有初始化,如果是呼叫派生類中的Func,會造成錯誤,記憶體越界甚至崩潰。 在函式中,可以通過列印虛表地址: -- Base::Func() int* vtl = (int*)*((int*)this); std::cout << "Base: " << this << "  VTable: " << vtl << std::endl; -- Deri::Func() int* vtl = (int*)*((int*)this); std::cout << "Deri: " << this << "  VTable: " << vtl << std::endl; 輸出: Base: 0028F980  VTable: 003FDC78
Deri: 0028F980  VTable: 003FDC98 發現,虛表的地址是不斷變化的。