② (不能有子對象的初始化,因為)
第二題
B bb[2]; //定義兩個 B 對象,每定義壹個無參的 B 對象,先調用 B 的基類 A 的默認構造函數,然後初始化數據成員int b,A aa,再壹次調用 A 的默認構造函數,最後調用類 B 的默認構造函數。上述過程發生兩次。
輸出:
A’s default constructor called.
A’s default constructor called.
B’s default constructor called.
A’s default constructor called.
A’s default constructor called.
B’s default constructor called
bb[0]=B(1,2,5); //聲明壹個臨時的 B 對象,構造函數的調用順序和上壹條代碼的類似,由這句代碼 B::B(int i,int j,int k):A(i),aa(j) 可知:先調用 B 的基類 A 的帶參默認構造函數,然後初始化數據成員 A aa,再壹次調用 A 的帶參構造函數,最後調用類 B 的帶參構造函數。因為是臨時對象,所以在這句代碼執行完以後,臨時對象 B 要被銷毀,所以依次調用析構函數,調用順序是:先調用類 B 的析構函數,再銷毀數據成員 A aa,調用用類 A 的析構函數,最後再調用基類 A 的析構函數。
輸出:
A’s constructor called.
A’s constructor called.
B’s constructor called.
B’s destructor called.
A’s destructor called.
A’s destructor called.
bb[1]=B(3,4,7); //同上。輸出:
第壹題:① (類的具體化或實例化是聲明類對象的操作)
② (不能有子對象的初始化,因為)
第二題
B bb[2]; //定義兩個 B 對象,每定義壹個無參的 B 對象,先調用 B 的基類 A 的默認構造函數,然後初始化數據成員int b,A aa,再壹次調用 A 的默認構造函數,最後調用類 B 的默認構造函數。上述過程發生兩次。
輸出:
A’s default constructor called.
A’s default constructor called.
B’s default constructor called.
A’s default constructor called.
A’s default constructor called.
B’s default constructor called
bb[0]=B(1,2,5); //聲明壹個臨時的 B 對象,構造函數的調用順序和上壹條代碼的類似,由這句代碼 B::B(int i,int j,int k):A(i),aa(j) 可知:先調用 B 的基類 A 的帶參默認構造函數,然後初始化數據成員 A aa,再壹次調用 A 的帶參構造函數,最後調用類 B 的帶參構造函數。因為是臨時對象,所以在這句代碼執行完以後,臨時對象 B 要被銷毀,所以依次調用析構函數,調用順序是:先調用類 B 的析構函數,再銷毀數據成員 A aa,調用用類 A 的析構函數,最後再調用基類 A 的析構函數。
輸出:
A’s constructor called.
A’s constructor called.
B’s constructor called.
B’s destructor called.
A’s destructor called.
A’s destructor called.
for(int i=0;i<2;i++)
bb[i].Print();
//相當於 bb[0].print();bb[1].print();
bb[0]是各數據成員的值如下
基類 A 中的 a = 0(類 A 的帶參構造函數中初始化為 0),int b = 5(類 B 的帶參構造函數中初始化為 5),A aa 中的 a = 0(同理基類 A 中的 a 的初始化)。
bb[0].print()可以還原為:
bb[0].A::Print();
cout<<bb[0].b<<“,”<<bb[0].aa.Geta()<<endl;
所以輸出為 0,5,0
同理,b[1].print()的輸出為:
0,7,0