1. 程式人生 > >effective c++條款09:絕不在構造和析構過程中呼叫virtual函式

effective c++條款09:絕不在構造和析構過程中呼叫virtual函式

#include <iostream>
using namespace std;

class BaseClass
{
public:
	BaseClass()
	{
		cout << "BaseClass" << endl;
	}
	~BaseClass()
    {
        cout << "~BaseClass" << endl;
    }
};

class DerivedClass:public BaseClass
{
public:
	DerivedClass:public ()
	{
		cout << "DerivedClass:public " << endl;
	}
	~DerivedClass()
    {
        cout << "~DerivedClass" << endl;
    }
};
int main()
{
	DerivedClass dc;
	return 0;
}

首先大家思考一下,上面這段程式碼輸出語句的執行順序?

執行結果:

這說明BaseClass的建構函式是先於DerivedClass的建構函式的,而DerivedClass的解構函式是先於BaseClass的。

那麼下面這段程式碼編譯後會發生什麼?

#include <iostream>
using namespace std;

class BaseClass
{
public:
	BaseClass()
	{
		PrintWho();
	}
	virtual ~BaseClass()
    {
        
    }
public:
	virtual void PrintWho() = 0;
};

class DerivedClass:public BaseClass
{
public:
	DerivedClass()
	{
		
	}
	~DerivedClass(){}
public:
	void PrintWho()
	{
		cout << "DerivedClass" << endl;
	}
};
int main()
{
	DerivedClass dc;
	return 0;
}

答案: 

 為什麼出現這種情況已經顯而易見了,連結器找不到PrintWho函式的定義,BaseClass中並沒有給出具體實現。

但是如果改成這樣:

#include <iostream>
using namespace std;

class BaseClass
{
public:
	BaseClass()
	{
		PrintWho();
	}
	virtual ~BaseClass()
    {
        
    }
public:
	virtual void PrintWho()
	{
		cout << "BaseClass" << endl;
	}
};

class DerivedClass:public BaseClass
{
public:
	DerivedClass()
	{
	}
	~DerivedClass(){}
};
int main()
{
	DerivedClass dc;
	return 0;
}

程式就可以正常執行。 

所以說,與其說“絕不在構造和析構過程中呼叫virtual函式”,不如說“不要在BaseClass的構造和析構中呼叫純虛擬函式”。