2012-07-25 81 views
1

函數需要返回指向StructAshared_ptr什麼是一個好的返回類型`boost :: shared_ptr <StructA>`?

struct StructA 
{ 
    // complicated struct that also holds other sub-structure 
    .... 
}; 

const boost::shared_ptr<const StructA&>& GetStructA(...) 
{...} #0.5 

const boost::shared_ptr<const StructA>& GetStructA(...) 
{...} #0 

const boost::shared_ptr<StructA>& GetStructA(...) 
{...} #1 

const boost::shared_ptr<StructA> GetStructA(...) 
{...} #2 

boost::shared_ptr<const StructA> 
{...} #3 

boost::shared_ptr<StructA> GetStructA(...) 
{...} #4 

boost::shared_ptr<StructA>& GetStructA(...) 
{...} #5 

boost::shared_ptr<StructA&> GetStructA(...) 
{...} #6 

有這麼多的選擇,我相信他們中的一個是最好的(請指出,如果還有人左)。

就個人而言,我更喜歡使用#0

const boost::shared_ptr<const StructA&>& GetStructA(...) 
{...} #0 

遺留系統使用#2

const boost::shared_ptr<StructA> GetStructA(...) 
{...} #2 

爲什麼我寧願選擇#0是如下原因:

  1. 返回常量shared_ptr的,使得該函數的調用者不應改變返回的shared_ptr其可以指向內部數據結構

  2. 返回通過引用,這樣我可以避免+/-的shared_ptr的引用計數的

  3. shared_ptr保存const StructA &,以便調用方不能更改const shared_ptr的內容。如果我是對的,即使shared_ptr是const,它也不能阻止調用者改變指向的數據,除非數據是const。

  1. 糾正我的理解,如果我沒有犯錯
  2. 提供此功能的最好回報簽名。

謝謝

+0

你不想讓他做shared_ptr'X =其他值'或者你不想'(* X)=其他值'? – RedX 2012-07-25 15:26:12

+2

2>這是*非常危險*,通過顛覆共享指針的整個目的。你現在有一個指針,認爲它被使用了3次,但是真的被使用了6,並且在3次發佈(segfault)後使用時不會拋出。它也可能嘗試自我釋放6次,因爲示波器在每個參考上都會關閉。 – ssube 2012-07-25 15:28:06

+4

我甚至沒有意識到它是合法的*使共享指針包含引用類型... Eeevil – jalf 2012-07-25 15:33:30

回答

2

這將取決於函數的功能:

  • 是它創造StructA的新對象?如果是,那麼你必須返回一個shared_ptr的副本。
  • 它只是提供對StructA對象的訪問,您知道它不會在返回的引用下過期嗎?然後,你可以在它返回常量&(但不 - 見下文)

正如你犯罪嫌疑人,對的shared_ptr不會阻止對象非const訪問常量&它指向 - 它只是手段該shared_ptr對象本身是常量,不能被重置或指向其他對象。在這種情況下,shared_ptr的語義與普通指針的語義相同。

我在返回訪問指針時習慣使用const &。但最後它會導致非常微妙的錯誤,特別是在多線程代碼中(我很小心,但我仍然被咬傷)。所以上面的peachykeen的評論是很重要的,我遵循那個所有新代碼的習慣用法。不僅僅是爲了讓你回想起你,而且當函數參數是一個shared_ptr時。在最後你真的想知道,只要你有一個由shared_ptr指向的對象 - 你真的有它,而不僅僅是一個長期死對象的shared_ptr的引用。

相關問題