1,爲什麼要用虛函數? 因爲在使用基類的引用或指針調用一個虛成員函數時會執行動態綁定。這樣,程序直到運行時才能知道到底調用了哪裏的虛函數,從而實現了多態。
2,base *pBase = new son;的執行順序:首先調用了基類的默認構造函數(由派生類構造函數調用),再調用了派生類的默認構造函數。當然,由於基類的析構函數沒有設置爲虛而造成的內存泄漏大多也是由於有這樣的語句纔會造成。
3,base *pBase = new son;這條語句後發現pBase並不能調用派生類中新增的函數,爲什麼要用這樣的語句呢?因爲它可以實現多態性,即向不同的派生類對象發送同一個消息,不同的對象在接受時會產生不同的行爲(通過調用各自相同名字不同作用的虛函數實現)。
4,執行delete pBase;如果基類的析構函數爲虛,則先執行派生類的析構函數,再執行基類的析構函數
如果基類的析構函數不爲虛,則只執行基類的析構函數。此時泄漏內存
// 虛析構函數造成內存泄漏的一些探索
#include <iostream>
using namespace std;
class base
{
public:
base() // 基類的默認構造函數
{
cout << "執行到基類構造函數!" << endl;
}
void cout1() // 基類中的一個非虛函數
{
cout << "執行到基類非虛函數!\n";
}
virtual void cout2() // 基類的一個虛函數
{
cout << "執行到基類的虛函數!\n";
}
virtual ~base() // 基類的虛析構函數
{
cout << "執行到基類虛析構函數!\n";
}
};
class son : public base
{
public:
son() // 派生類的構造函數
{
cout << "執行到派生類構造函數!\n";
}
void cout1() // 派生類的非虛函數
{
cout << "執行到派生類非虛函數!\n";
}
virtual void cout2() // 派生類重寫虛函數
{
cout << "執行到派生類重寫的基類虛函數\n";
}
void cout3() // 派生類中新增的函數
{
cout << "派生類獨有的成員函數\n";
}
~son()
{
cout << "派生類析構函數\n";
}
};
void main()
{
base *pBase = new son;
pBase->cout1(); // 執行到基類非虛函數!
pBase->cout2(); // 執行到派生類重寫的基類虛函數,無論派生類的函數是不是virtual;
//pBase->cout3(); // error C2039: 'cout3' : is not a member of 'base'
delete pBase;
}