在學習《C++primer 第五版》(中文版)中第七章類的時候遇到了一個有意思的習題,原題如下:
練習7.43:假定有一個名為NoDefault的類,它有一個接受int的建構式,但是沒有默認的建構式,定義類C,C有一個Nodefault型別成員,定義C的默認建構式
本題的答案很簡單,直接利用初始化串列給成員類提供一個默認引數即可,參考答案如下:
struct Nodefault { private: int x; public: Nodefault(int y){}; }; struct C { private: Nodefault no; public: C() :no(1) {}; };
但是當時想利用一個為所有引數都提供默認實參的建構式來等價定義默認函式,于是將C的建構式改為下式:
C(Nodefault x= Nodefault(1)) :no(x) {};
初看這個建構式的時候非常難以理解,本能的會將此行代碼理解為:呼叫建構式Nodefault(int)將其回傳值當成x的默認初始值并利用串列初始化提供成員類no的初始值,這樣理解有兩個問題:
首先是建構式是一個沒有回傳值的特殊函式,其次沒有回傳值的建構式無法給"="提供一個有效的右值,
顯然這樣的理解是錯誤的,正確的執行流程應該是:
1、顯式呼叫類Nodefault的建構式Nodeafult(int),生成一個類的臨時物件,
2、呼叫拷貝建構式將臨時物件拷貝給類C的成員類no(只呼叫一次拷貝建構式),
驗證代碼如下:
struct Nodefault { private: int x; public: Nodefault(int y) { cout << "consttuction for Nodefault" << endl; }; Nodefault(const Nodefault &c) { x = c.x; cout << "copy construction" << endl; } ~Nodefault() { cout << "deconstruction for Nodefault" <<endl; } }; struct C { private: Nodefault no; public: C(Nodefault x= Nodefault(1)) :no(x){ cout << "consttuction for C" << endl; }; ~C() { cout << "deconstruction for C" << endl; } }; int main() { C object; return 0; }
輸出結果如下:
1 consttuction for Nodefault 2 copy construction 3 consttuction for C 4 deconstruction for Nodefault 5 deconstruction for C 6 deconstruction for Nodefault
注意:1、只呼叫一次拷貝建構式,臨時物件直接拷貝給成員類,
2、兩次呼叫類Nodefault的解構式:第一次在C物件建構式結束時析構臨時物件Nodefault、第二在程式結束時自動析構C后析構成員類Nodefaul
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/277608.html
標籤:C++
上一篇:馬上就要畢業實習
