2014-01-05 26 views
1

鑑於原型:重載函數時使用臨時對象作爲參數是否是一種好的做法?

void foo(int i); 
void foo(int i, const std::string &s); 

實現:

void foo(int i) 
{ 
    foo(i, std::string()) ; 
    //! ^^^^^^^^^^^^^ ^here? 

    // nothing more. 

     } 
//! ^here? 

void foo(int i, const std::string &s) 
{ 
    //do something 
} 

哪裏由std::string()創建的臨時對象走出去的範圍有多大?以這種方式重載函數是一種很好的做法嗎?

更新:

讓我解釋的情況一點點。作爲練習,我正在嘗試編寫一個類似std::vector的類,而不使用模板。它唯一的類型是std::string。班級正文可在another question找到。

在實現resize()成員函數,我發現std::vector似乎使用了兩個功能:

所以我不知道我是否應該使用的,而不是單一的一個兩個功能。

+0

如果不理解預期的語義,真的不可能給出一個好的答案。如果兩個'foo'都做同樣的事情,給它們起同樣的名字是有道理的,那麼爲什麼只需要更少的參數就需要調用更多的東西,然後做更多的東西呢?這些東西是微不足道的(日誌?)還是界面的一個可見部分,這樣一個'foo'在外部就可以理解爲不同於另一個? –

+0

隨着編輯,關於生命期的問題沒有多大意義。 – Mat

+0

@DavidSchwartz你好我已經更新了線程。希望它能讓情況更清楚。 –

回答

2

我不認爲這是不好的做法,特別是如果你使foo(int i)內聯。這是最好的時候,我能想到的理由:當您創建的指針的功能,如果你聲明的第二個參數默認情況下,你只能有指針接受2個參數的功能。

臨時值活着纔有作爲函數調用的參數。

inline void foo(int i) 
{ 
    foo(i, std::string()); 
} 

void foo(int i, const std::string &s) 
{ 
    //do something 
} 
+0

爲什麼內聯?讓它更快? –

3

不,這不是一個好的做法,至少在這個特定的情況下。使用一個單一的功能,併爲參數的默認值,而不是兩個功能,其中一個似乎只存在提供一個默認的說法:

void foo(int i, const std::string &s = "") 
{ 
    //do something 
} 
+0

在這種情況下似乎確實如此。 – meagar

+0

你可能想說'std :: string()'而不是'''',以防萬一實施發生爲空文本分配內存。 – Mehrdad

+0

@meagar嗨!我更新了線程。希望它能讓情況更清楚。 –

1

唯一的「危險」,在傳遞一個暫時的const&發生,如果該函數創建一個生存函數調用本身,其存儲本身const&的對象。

認爲

class A 
{ 
    const string& a; 
public: 
    A(const string& a) :a(a) {} 
    void act() { .... /* use a */ } 
}; 

A* foo(const string& s) 
{ return new A(s); } 

int main() 
{ 
    A* pa = foo(string()); 
    //here, pa->act() will act on a dangling reference. 
} 

如果您foo功能只是使用字符串,但不保留供以後使用的參考,通過臨時是絕對安全的。

如果發生這種情況使用「開機功能」或默認臨時值使得對生成的代碼沒有什麼區別。

在這一點上,使用一個或兩個函數更多的是風格和機會問題:在進一步開發過程中,兩個函數有多少區別?

如果答案是「沒有:第二個功能是非常頻繁的情況下,只需定義(或快捷方式)」比默認值完美地完成這項工作。

如果答案是「讓我們回落到其他功能現在,後來更具體」,然後的兩個函數被preferrable。

默認值都是然而,這不是的情況下,有機會的功能是模板,你想類型推演工作:

template<class C, class T> 
void fn(int i, basic_string<C,T>& s = ????); 

你不能使用的std :: string(),因爲它不會爲C其他工作比char,並且不能使用std::basic_string<C,T>(),因爲它不允許在調用fn(5)時知道C和T應該是什麼。

所以,你會最終了

void fn(int i) { fn(i,string()); } 

相關問題