簡體   English   中英

在現代C ++中使用非智能指針

[英]using non-smart pointers in modern C++

簡潔版本:
在現代C ++中使用非智能指針有什么可接受的理由嗎?

長版:
我們有一個巨大的產品,包含很多舊的C ++代碼,現在我們正在嘗試將它重構為現代C ++時代。 除了所有舊式代碼之外,還有大量的指針傳遞(主要是使用SAL注釋來提供一些安全感),我想知道是否應該將它們全部更改為智能指針,或者可能將其中的一些保留為智能指針。 ?
試圖轉換其中的一些代碼,我最終得到了一個代碼,它可以簡單地論證使用智能指針

所以問題是:是否存在使用智能指針這樣的事情?
換句話說:這些天非智能指針是否有可接受的場景?

智能指針( unique_ptrshared_ptr )應該是OWNING指針(即負責銷毀對象)。 使用它們的底線是, new創建的任何對象都應該被推送到unique_ptr ASAP中,以防止內存泄漏。 之后, unique_ptr應該最終被移動:

  • 如果所有權應該共享,要么進入shared_ptr
  • 如果所有權由范圍(塊或對象的生命周期)確定,則為或者為unique_ptr

release應該是罕見的。 如果您的代碼傳遞非擁有指針,則應該是:

  • 原始指針,如果它們可能為null ,(通過get
  • 引用,如果它們可能不為null ,(通過get
  • 如果呼叫的目的是轉移所有權,則unique_ptr按值。 (在這種情況下你需要移動它們)

工廠方法應按值返回unique_ptr (因為那時,如果你沒有指定工廠方法的返回值,則立即取消分配對象)

並查看Ali關於處理遺留代碼的一些哲學觀點的鏈接的答案。 (我完全贊同)

是的,原始指針仍然用作“可選參考”。 T*類似於T& 既不暗示所有權,但T*可以是nullptr

簡潔版本:
在現代C ++中使用非智能指針有什么可接受的理由嗎?

簡短回答:

當然,如果它們只用於觀察,也就是說, 它們不擁有指針。 但是,即使在這種情況下,也嘗試使用引用而不是指針; 只有當你真的需要使它們成為可選項時才使用指針(例如,使用null_ptr初始化然后再重新分配)。

長版:
我們有一個巨大的產品,包含很多舊的C ++代碼,現在我們正在嘗試將它重構為現代C ++時代。 [...]

答案很長:

在我閱讀這些內容時,我想到了這個答案:

我希望我能不止一次地回答這個問題。 我會引用: “[...]對於我們所做的每一個重新因素我們可以證明'這一具體的改變將使我們現在正在做的實際任務更容易'。而不是'現在這對於未來的工作來說更加清潔'。”

長話短說,除非你真的需要,否則不要做大的重構。

所以問題是:是否存在使用智能指針這樣的事情?

在我看來, std::shared_ptr被過度使用了。 它使用起來非常舒適,它給你的幻覺是你不必考慮所有權問題。 但這不是全局。 我完全同意Sean Parent“共享指針和全局變量一樣好。” 共享指針也可能引入非常困難的所有權問題等。

另一方面,如果需要在堆上分配內容,請使用unique_ptr 如果你真的需要堆分配,你不能過度使用它。 根據我的經驗,使用unique_ptr還可以使代碼更清晰,更易於理解,因為所有權問題變得不言自明。

Sean Parent關於如何避免/減少指針使用的有趣談話是:

希望這可以幫助。

在這里查看會談: http//channel9.msdn.com/Events/GoingNative/2013 (特別是Stroustrup的演講)。

簡短的回答是否定的,假設“現代C ++”是> = c ++ 11

長期的答案並非總是如此,試圖重組大型項目幾乎總是很難。 我們思考問題的方式受到我們解決問題的工具的限制。 有很多情況下進行這樣的重構時,使用指針比嘗試將基本邏輯重新表達為類和智能指針友好更簡單。 我認為這不是智能指針過度使用的情況,而是在使用類時更多的情況。 YMMV ;-)

當然在現代C ++中有原始指針的用例:

  • 必須可編譯為純C的接口(盡管實現本身可能會利用那些C ++特性,而不是C特性,如類或智能指針)
  • 代碼是極低級別,如此低級別,甚至最簡單的智能指針證明是重量級

當然這些是相當罕見的情況,到目前為止,指針智能指針的大多數用例應該適用於新代碼,但是:

如果現有代碼與原始指針一起正常工作,為什么要花時間重寫它,並且在使用版本將其轉換為智能指針時冒險添加錯誤?

不要重構代碼,工作正常,只是因為新代碼更好地遵循現代編程標准。 這些編程標准本身並不存在,但是為了更容易地使用某些代碼,所以不要進行重構,這將花費您比將來節省您更多的時間。

這意味着:如果它將花費你更多的時間來檢查,哪些指針可以安全地轉換為智能指針,哪些不能並且可以捕獲錯誤,你的重構可能已經引入,而不是你將能夠保存由於重構,未來的維護工作,然后只是不重構,讓它保持原樣。

如果重構將比僅為代碼庫的某些部分節省更多的時間,那么考慮只重構代碼庫的那些部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM