2017-02-14 56 views
1

這是一個非常簡單的問題。假設我有一類檢查構造函數與設置函數

class A 
{ 
public: 
    A(int); 
    void setA(int); 
private: 
    int a; 
}; 

與實施

A::A(int a_) : a(a_) { } 
void A::setA(int a_) { a = a_; } 

比方說,我想避免a = 0但我不想拋出異常,我只是想保持一個有效的對象與a = 1而不是在那種情況下(爲什麼現在沒有關係)。

然後,我可以在構造函數中添加一個if語句,並在setA中檢查參數是否爲0,並在該情況下將其設置爲1。從概念上講,這告訴我,在這種情況下,我應該更改構造函數,而不是在那裏初始化a,我應該在構造函數中調用setA。通過這種方式,檢查代碼只寫入一次(請記住,這是一個簡單的情況,但驗證在其他情況下可能會更復雜)。

現在,該方法涉及在構造函數中調用額外的函數。兩次編寫驗證代碼效率更高嗎?那麼如果setA只是偶爾使用呢?

+2

無論如何可能會內聯,將其添加到'setA'並在構造函數中調用'setA'。不要擔心這些(似乎是但實際上不是)性能差異。寫乾淨的代碼。優化器將爲您完成剩下的工作。 –

+1

你不需要重命名參數:'A :: A(int a):a(a){}'很好。 – nwp

回答

1

我同意你的激情來防止代碼重複。只是要小心過度,1班輪可能會過度。

如果你打算做檢查,雖然你應該使用一個實現文件的功能或privatestatic的方法來做到這一點:

int preventZero(const int a_) { return a_ == 0 ? 1 : a_; } 

然後你就可以在你的實現使用它,如下所示:

A::A(int a_) : a(preventZero(a_)) { } 
void A::setA(int a_) { a = preventZero(a_); } 
1

在構造函數中使用驗證調用setter肯定會更好,因爲代碼重複是邪惡的。您也可以將其內聯以確保您不會浪費CPU週期,但我認爲這是過早的優化。

+1

現代編譯器不聽'inline'。 –

+0

有編譯器特定的屬性強制內聯AFAIK,比如__forceinline for VS – dmsovetov

+0

@GillBates除了使你的代碼不可移植之外,'__forceinline'告訴編譯器忽略它更好的判斷和使用你的代碼。請不要使用這種'__forceinline'。 –