2013-03-13 105 views
3

我已經開始利用的std::unique_ptr例如爲:我的函數應該接受指針還是智能指針?

unique_ptr<TFile> myfile(TFile::Open("myfile.root")); 

,而不是

TFile * myoldfile = TFile::Open("myoldfile.root") ; 

現在我不知道我的職能應該是什麼樣子。我認爲問題的一部分可能是我的代碼不夠複雜,但任何問題都會變得明顯,但我希望立即得到它,所以當事情更加複雜時,我不會陷入混亂。

我曾經有:

double interestingResult(TFile * input) 
{...} 

(不實際修改TFile但不能是const,因爲它要求TFile的一些非const函數)。

我仍然可以做稱之爲:

myResult = interestingResult(myfile.get()); 

這似乎很人性化不是。 (我想在這裏建議:https://stackoverflow.com/a/5325560/1527126

或者,我可以修改我的函數看起來像:

double interestingResult(unique_ptr<TFile>& input) 
{...} 

迫使用戶始終使用的unique_ptr。

我也可以寫支持:

double interestingResult(unique_ptr<TFile>& input) 
{ return interestingResult(intput.get()); } 

,但我不明白,在別人的代碼。

這種情況的標準方法是什麼?

我想這個答案(https://stackoverflow.com/a/9700189/1527126)意味着我應該接受引用,因爲我不希望myfile爲空。但是函數庫函數TFile::Open總是返回一個指針,所以看起來很自然,可以直接將該函數傳遞給函數,而不需要額外的解引用。

歉意p.s.我放棄了試圖弄清楚我是否應該問StackOverflow或CodeReview,或者根本沒有,但請指出我適當的地方,如果不是這樣。

+0

使用參考? – Nim 2013-03-13 16:36:29

回答

2

參考TFile &或指針TFile *是好的。

有些人會告訴你,當空指針是函數的無效輸入時,你應該「使用」一個引用。當他們嘗試使用從C繼承的std::strlenstd::memcpy等標準函數時,這些人會感到困惑和憤怒。我的感覺是,儘管使用引用自身文檔的引用是需要referand的,但它也是很好的你的API工作要麼與引用一致,要麼與指針一致。

有些人會告訴你「不應該」使用非const引用參數,而寧願使用指針。當他們嘗試使用標準函數如std::swap時,他們會感到困惑和憤怒,因爲對於一個看似傳遞值的C程序員來說,它「不應該」修改輸入。

只要你不與這些人一起工作,你可以自己選擇。

+0

當NULL值無效時使用指針類型定時會導致維護問題。充其量,它充分利用了NULL的運行時問題 - 需要重複檢查和通道來指示錯誤情況。否則它會導致崩潰或更糟,如果有一個NULL可以滑過的調用路徑。如果它的項目風格或者你害怕非const引用,那就是你必須做的 - 但是你應該知道後果。僅供參考:我不害怕在C(-style)代碼中使用'strcpy',但是當我獲得選擇時,我會使用字符串類而不是裸C字符串。 – JoergB 2013-03-13 17:02:03

+1

@JoergB:我沒有看到那些經常維護的問題,在採用指針的代碼中更糟糕。那種在文檔中不檢查'null'是否是有效輸入(即幾乎任何人,在足夠糟糕的一天)都不會在引用指針之前檢查空值的麻煩的人。所以他們只是將'* p'傳遞給需要引用的函數,有時'p'在代碼中爲空,並且有人必須查找並修復它。 – 2013-03-13 17:03:28

+1

和FWIW,當我嘗試使用帶指針的函數時,我變得困惑和憤怒,但不明確地說空輸入是否有效,因爲對於作者來說,按照約定顯而易見的是,如果函數接受一個指針,則空有效;-) – 2013-03-13 17:09:15

3

接受參數列表中的智能指針的問題是您指定調用者可以使用哪種智能指針。例如,通過使用unique_ptr,您可以防止調用方使用shared_ptr。

在你的情況下,我會建議一個參考參數。我也看到很多常用的指針。最主要的是你的函數不會在函數返回後試圖持有一個引用/取得對象的所有權 - 也就是說它不會在後來釋放內存。

1

它取決於,但在函數中使用原始指針(或對象的引用),因爲函數不會接受指針的所有權。

和如果有一天你會決定使用shared_ptr的...

4

你指的是正確的答案。

如果有,應該在任何現有TFile比如工作,沒有理由接受NULL指針作爲一個有效參數,其中函數的論據沒有所有權,你應該使用TFile&作爲參數類型(TFile const&在可能的功能)。傳入的對象由指針保存(不論是否擁有所有權)指針應該不會影響該函數。

您可以選擇使用TFile *參數,但這會在傳遞NULL的有效性方面造成至少不明確性,因此可能會在將來導致問題。

如果您使用unique_ptr<TFile>參數,則將對象的所有權轉移給該函數以保持良好狀態。呼叫返回時,呼叫方將留下NULL unique_ptr

如果使用unique_ptr<TFile>&參數,則表示函數可以選擇接管對象的所有權或將其留給調用者。相當不尋常。

A unique_ptr<TFile> const&參數可以像TFile *一樣使用,但強制調用方擁有該對象並使用unique_ptr來管理該對象。爲什麼要對呼叫者施加這樣的要求?當然這(和unique_ptr的其他用途)都必須處理NULL情況。