虛表指針初始化順序

無繼承時:

1、分配內存
2、初始化列表之前賦值虛表指針
3、列表初始化
4、執行構造函數體

有繼承時:

1、分配內存
2、基類構造過程(按照無繼承來)
3、初始化子類虛表指針
4、子類列表初始化
5、執行子類構造函數體

Q:虛表指針在初始化列表之前被賦值,可以放在初始化列表之後賦值嗎?即順序是:列表初始化、虛表指針賦值、構造函數體??

class B
{
public:
	virtual int size(){return 0;}
};


class A:public B{
public:
	int m_a; 
	A():m_a(size())   //在初始化列表中調用了虛函數(應該是A類的size()函數,不應該是B類的size()函數)
	{
		cout<<m_a<<endl;
	}
	virtual int size(){
		//cout<<2<<endl;
		return 1;}
};

int main()
{
	A a;
	return 0;
}

解答:如果虛表指針的初始化在初始化列表之後的話,可能會出現如上代碼所示的情況:也就是說,在初始化列表中使用了一個虛函數!!!
那麼在調用此虛函數的時候,應該訪問哪個虛表呢?是基類的虛表?還是當前類的虛表?

毫無疑問,應該是當前類的虛表!!!
但是在調用此虛函數的時候,虛表指針並未賦值爲子類的虛表,所以無法訪問當前類的虛函數,訪問的依舊是基類的虛函數。

因此,將虛表指針的賦值過程應該放置在初始化列表之前,這是爲了放置在初始化列表出現調用虛函數的情況!!!

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