1、構造函數和析構函數為什么沒有返回值?


構造函數和析構函數是兩個非常特殊的函數:它們沒有返回值。這與返回值為void的函數顯然不同,后者雖然也不返回任何值,但還可以讓它做點別的事情,而構造函數和析構函數則不允許。在程序中創建和消除一個對象的行為非常特殊,就像出生和死亡,而且總是由編譯器來調用這些函數以確保它們被執行。如果它們有返回值,要么編譯器必須知道如何處理返回值,要么就只能由客戶程序員自己來顯式的調用構造函數與析構函數,這樣一來,安全性就被人破壞了。另外,析構函數不帶任何參數,因為析構不需任何選項。

如果允許構造函數有返回值,在某此情況下,會引起歧義。如下兩個例子

class C
{
public:
    C(): x(0) {    }
    C(int i): x(i) {   }

private:
    int x;


};

如果C的構造函數可以有返回值,比如int:int C():x(0) { return 1; } //1表示構造成功,0表示失敗
那么下列代碼會發生什么事呢?
C c = C();  //此時c.x == 1!!!
很明顯,C()調用了C的無參數構造函數。該構造函數返回int值1。恰好C有一個但參數構造函數C(int i)。於是,混亂來了。按照C++的規定,C c = C();是用默認構造函數創建一個臨時對象,並用這個臨時對象初始化c。此時,c.x的值應該是0。但是,如果C::C()有返回值,並且返回了1(為了表示成功),則C++會用1去初始化c,即調用但參數構造函數C::C(int i)。得到的c.x便會是1。於是,語義產生了歧義。使得C++原本已經非常復雜的語法,進一步混亂不堪。

構造函數的調用之所以不設返回值,是因為構造函數的特殊性決定的。從基本語義角度來講,構造函數返回的應當是所構造的對象。否則,我們將無法使用臨時對象:
void f(int a) {...}  //(1)
void f(const C& a) {...} //(2)
f(C()); //(3),究竟調用誰?
對於(3),我們希望調用的是(2),但如果C::C()有int類型的返回值,那么究竟是調(1)好呢,還是調用(2)好呢。於是,我們的重載體系,乃至整個的語法體系都會崩潰。
這里的核心是表達式的類型。目前,表達式C()的類型是類C。但如果C::C()有返回類型R,那么表達式C()的類型應當是R,而不是C,於是便會引發上述的類型問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM