測試源代碼:
//測試派生類的構造函數的調用順序何時調用
//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;
}
輸出為:

能夠看到,在建立派生類的對象的時候,首先調用的是基類中的構造函數,然後才是調用派生類自己的構造函數。
而在析構的時候。順序則剛好相反。先調用派生類的析構函數,然後才是調用基類的構造函數,這是由于對象建立時候對象存放在堆棧中的原因。
(new 的對象盡管是存在堆中,可是在堆棧中依舊存放其堆中的位址,是以,析構的時候也是一樣)
那麼,建立其對象的數組時:A a[2],是否會調用其構造函數呢,這是肯定的,例如以下
測試代碼:(僅改動main裡面的内容)
int main()
{
A a[2];
}
結果為:
那假設是建立指向其對象的數組呢? 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筆試做這道題的時候。析構的順序似乎弄錯了。郁悶。
還沒收到面試資訊,也還沒有受到筆試挂了的通知。也不知道是個什麼情況啊。
繼續努力吧。