2013-10-17 79 views
0

我們使用C++ 98(較舊的一個)。返回對智能指針的const引用vs使用引用作爲參數

比方說,我們有一張桌子,並考慮查找。 Ptr是一些智能指針。 下面的語句1. - .3正確或兩種情況都考慮從呼叫者的角度來看是同樣安全/不安全 ?查找的

函數原型:

const Y::Ptr & lookup(const X::Ptr & x); 

和呼叫者函數,其中查找叫做:

const Y::Ptr & ret = lookup(x); 

其中,x是X :: PTR對象或X :: PTR的參考。所以,我們有以下兩行的用法。

  1. 函數參數const X::Ptr &。這通常是安全的,並避免函數調用時複製構造函數X::Ptr。調用者負責爲對象X保留X的引用,以在查找函數調用的持續時間內持續。
  2. 返回值const Y::Ptr &。這是不安全的,因爲在此引用位於堆棧中的短暫持續時間內,如果線程被中斷/掛起並且另一個線程從表中刪除條目,則Y對象和Y::Ptr對象都將被刪除。結果,堆棧上的Y::Ptr引用引用了一個不存在的Ptr對象。
  3. 本地參考const Y::Ptr &來存儲查找的返回值。這是不安全的,因爲#2類似的原因,但可能更糟,因爲調用方函數中的本地引用的作用域比堆棧上的ref長作爲返回值。

回答

0

我想你已經明白了。顯然,解決方案是按值返回智能指針。請注意,您的#2點完全被#3包含,所以沒有太多需要特別考慮點#2(因爲沒有關於您沒有或者不能使用的參考點)。

0

很大程度上取決於lookup的作用,以及您正在嘗試以什麼方式實現 。你邏輯上返回一個值,還是參考某些內部數據?在很多功能名稱爲 (如lookup)的情況下,它是後者,並且返回值作爲參考通常很重要。 (一個明顯的例子是 函數,如operator[],在std::vector。)但是,除非 語義需要參考,但是,您最好根據值返回 。

類似的,在呼叫站點。如果調用者需要參考 您的數據結構,他應該聲明變量爲 作爲參考;否則,他應該宣佈它是一個價值。 ( 當然,如果函數返回一個值,那麼從來沒有任何 合理的情況,其中局部變量應該是一個參考。)

我覺得多線程是一個紅鯡魚在這裏。如果其他線程 正在修改數據結構lookup的使用,則需要 外部同步,句點。如果函數返回 作爲參考,並將其保留爲參考,則關鍵 部分包含參考的有效期,但這通常不是一個大問題;如果是,則調用者可以將 結果存儲爲一個值,並用它來完成。

作爲一般規則,C++更喜歡值語義。語言是 優化考慮到這一點,包括特殊規則允許編譯器 優化不必要的副本。不要打 吧。關於唯一的例外情況是使用 const作爲函數參數的參考。 (但是即使在這裏,你想要的是 一致,無處不在的約定是通過 引用const類型的引用,其他類型的值如果這是在你的代碼中使用的規則 ,那麼系統地使用它,而不是 異常)

+0

這個問題不僅僅是參考vs值,而是在初始文章中描述的兩個問題中哪一個更爲安全。 – user2890398