說明以下程序的顯示結果:
#include <iostream>
using namespace std;
class A
{
public:
A() {hello();}
~A() {hello();}
virtual void hello()
{
cout<<"Hello A"<<endl;
}
};
class B:public A
{
public:
B() {hello();}
virtual void hello()
{
cout<<"Hello B"<< endl;
}
};
int main()
{
A *ptr = (A *)new B();
//B *ptr = new B();
ptr->hello();
delete ptr;
return 0;
}
顯示結果:
Hello A
Hello B
Hello B
Hello A
解析:
A *ptr = (A *)new B();一句:初始化B類的時候先調用其父類(A)的構造函數,再調用B類的構造函數
ptr->hello();一句:ptr指向的是B類,盡管ptr本身是A*類型的指針,但還是調用B類的hello()函數
delete ptr;一句:B類沒有定義析構函數,只調用A類的析構函數,這裡即使B類定義了析構函數也不會被調用,除非在A類的析構函數前加上virtual
附別人的講解:http://www.cnblogs.com/findumars/archive/2013/10/08/3357626.html
主要結論:
刪除子類指針,無論如何會自動調用祖先類的析構函數(即使祖先類的習慣函數不是虛擬的)
自己類型的指針指向自己的對象,怎麼樣都沒有問題(不管父類析構函數寫不寫virtual)。只有基類指針指向子類對象的時候,一定需要virtual關鍵字的配合,才能正確的工作