天天看點

c++學習筆記4,派生類的構造函數與析構函數的調用順序(一)

測試源代碼:

//測試派生類的構造函數的調用順序何時調用
//Fedora20 gcc version=4.8.2
#include <iostream>
using namespace std;

class base
{
public:
	base()
	{
		
		cout<<"base created!"<<endl;
	}
	~base()
	{
		cout<<"base destroyed!"<<endl;
	}
};
//公有繼承
class A:public base
{
public:
	A()
	{
		cout<<"A created!"<<endl;
	}
	~A()
	{
		cout<<"A destroyed!"<<endl;
	}
};
class B:public A
{
public:
	B()
	{
		cout<<"B created!"<<endl;
	}
	~B()
	{
		cout<<"B destroyed!"<<endl;
	}
};      

測試代碼:

int main()
{
	A a;
	<span style="color:#ff0000;">A *a1;</span>
	cout<<"能夠看到a1并沒有調用基類的構造函數"<<endl;
	<span style="color:#ff0000;">A *a2=new A;</span>
	//僅僅有在new 一個對象的時候才會調用基類的構造函數
	cout<<"能夠看到a3也并沒有調用基類的構造函數"<<endl;
	A *a3=&a;      
B b;
}      

輸出為:

c++學習筆記4,派生類的構造函數與析構函數的調用順序(一)

能夠看到,在建立派生類的對象的時候,首先調用的是基類中的構造函數,然後才是調用派生類自己的構造函數。

而在析構的時候。順序則剛好相反。先調用派生類的析構函數,然後才是調用基類的構造函數,這是由于對象建立時候對象存放在堆棧中的原因。

(new 的對象盡管是存在堆中,可是在堆棧中依舊存放其堆中的位址,是以,析構的時候也是一樣)

那麼,建立其對象的數組時:A a[2],是否會調用其構造函數呢,這是肯定的,例如以下

測試代碼:(僅改動main裡面的内容)

int main()
{
	 A a[2];
}      

結果為:

c++學習筆記4,派生類的構造函數與析構函數的調用順序(一)

那假設是建立指向其對象的數組呢? A *a[2];

int main()
{
	 A *a[2];
}
      

答案顯然是不會。

那麼這個時候,假設A裡面有一個函數fun(),令a[0]->fun()會發生什麼情況呢?

void fun()
	{
		cout<<"A fun run"<<endl;
	}      
int main()
{
	 A *a[2];
	a[0]->fun();
}
      

能夠看到。盡管沒有調用構造函數,可是依舊能夠使其運作其成員函數呢!

那麼,假設A有一個public int i;的變量。a[0]->i。會是什麼?

class A:public base
{
public:
	int i;
	A()
	{
		cout<<"A created!"<<endl;
	}
	~A()
	{
		cout<<"A destroyed!"<<endl;
	}
	void fun()
	{
		cout<<"A fun run"<<endl;
	}
};      
int main()
{
	 A *a[2];
	a[0]->fun();
	cout<<endl<<a[0]->i<<endl;
}      

結果:

能夠看到,a[0]->i指向一個不确定的值!假設指定static const int i=1;那麼,指向的必定就是1了。

今天就先測試這些最簡單的吧。有點累了,多繼承,虛基層明天再測試。

突然發現好像上次UC筆試做這道題的時候。析構的順序似乎弄錯了。郁悶。

還沒收到面試資訊,也還沒有受到筆試挂了的通知。也不知道是個什麼情況啊。

繼續努力吧。