2010-04-15 47 views
2

我正在寫一個類,並且這個疑問出現了。這是undef。行爲?另一方面,我不確定它的推薦,或者它是一種好的做法。如果我確保在init函數中不會拋出異常,那麼它是否是一個?在構建實例之前調用非成員函數

//c.h 
class C{ 

    float vx,vy; 
    friend void init(C& c); 
public: 
    C(); 

}; 


//c.cpp 
C::C() 
{ 
    init(*this); 
} 

void init(C& c) //throws() to ensure no exceptions ? 
{ 
    c.vx = 0; 
    c.vy = 0; 
} 

在此先感謝

+0

爲您析構函數你沒有提供的主體。只要刪除它。 – 2010-04-15 04:22:12

+0

@epronk。它的示例代碼可以正確顯示。 – Tom 2010-04-15 04:24:51

+0

'throw()'不能確保不會有任何異常,它會添加一個運行時檢查,如果有異常通過,它將調用terminate(或其他gorgons之一)。不幸的是,沒有編譯時檢查異常規範......即將推出的標準將添加'noexcept'關鍵字,以確保一種方法永遠不會拋出,但是由程序員來確保它,並且如果它曾經拋出未定義行爲的可怕境界。 – 2010-04-15 07:05:54

回答

6

這是完全沒問題。一旦你進入構造函數的主體,所有的成員都已經初始化並且可以使用。 (然後,身體完成需要完成的任何工作,以創建一個完全構造的物體。)

但是它的風格很差。更好的是:

C::C() : 
vx(), vy() // or vx(0), vy(0) if you prefer to be explicit 
{} 

並且消除所有的混亂。


異常與安全無關,構造函數可以隨意丟棄。事實上,如果你不能成功構建一個對象,那麼拋出異常是首選的行爲。

+0

謝謝,異常部分清除了一些疑惑。可以這樣做 class C {float vx(); float vy(); public:...} ;? – Tom 2010-04-15 04:40:59

+0

...意思是「等等」,而不是不正確使用可變參數。 – Tom 2010-04-15 04:41:26

+0

@Tom:它*好,但不是你想要的。 (提示:那些看起來像我的功能:))不幸的是,沒有簡單的方法來說「嘿,讓這個零,所以我不必寫一個構造函數」。 – GManNickG 2010-04-15 04:42:31

0

當控件到達構造函數時,所有變量都會得到默認值。

+0

呃,一個聚合沒有初始化,它的值是不確定的。 – GManNickG 2010-04-15 04:31:20

0

我可以想到一個具體的情況,這可能會咬你。如果C旨在成爲一個基類,那麼允許引用它以轉義到非成員函數可能會引起意外。在基類的情況下,構造函數更加特殊,因爲派生類尚未構造,虛函數調用基類而不是派生類。非成員函數可能不期望在此狀態下獲得對象,並且因爲它們看起來不像構造函數,所以通過忘記引入錯誤會很容易。

它仍然不是未定義行爲雖然 - 只是令人驚訝的定義的行爲:)

相關問題