C++核心準則R.37: 不要使用從破損的智能指針​獲取的指針或引用

C++核心準則R.37: 不要使用從破損的智能指針​獲取的指針或引用

R.37: Do not pass a pointer or reference obtained from an aliased smart pointer

R.37: 不要使用從破損的智能指針獲取的指針或引用​

Reason(原因)

Violating this rule is the number one cause of losing reference counts and finding yourself with a dangling pointer. Functions should prefer to pass raw pointers and references down call chains. At the top of the call tree where you obtain the raw pointer or reference from a smart pointer that keeps the object alive. You need to be sure that the smart pointer cannot inadvertently be reset or reassigned from within the call tree below.

違反本規則是引用計數丟失和發生懸空指針的第一號理由。函數更應該沿著調用鏈向下傳遞原始指針和引用。你應該在調用樹的最頂端,從可以保證對象存在的智能指針獲得原始指針或引用。你需要保證智能指針不會在調用樹的下面被不小心重置或者重新賦值。

Note(注意)

To do this, sometimes you need to take a local copy of a smart pointer, which firmly keeps the object alive for the duration of the function and the call tree.

要做到這點,你需要獲取一個智能指針的局部拷貝,通過它可以在函數和調用樹執行期間將對象牢牢地鎖定。

Example(示例)

Consider this code:

考慮以下代碼:

<code>// global (static or heap), or aliased local ...
shared_ptr<widget> g_p = ...;

void f(widget& w)
{
g();
use(w); // A
}

void g()
{
g_p = ...; // oops, if this was the last shared_ptr to that widget, destroys the widget
}/<widget>/<code>

The following should not pass code review:

下面的代碼應該無法通過代碼評審:

<code>void my_code()
{
// BAD: passing pointer or reference obtained from a non-local smart pointer
// that could be inadvertently reset somewhere inside f or its callees
f(*g_p);

// BAD: same reason, just passing it as a "this" pointer
g_p->func();
}/<code>

The fix is simple -- take a local copy of the pointer to "keep a ref count" for your call tree:

為了改正這個問題--獲取指針的局部拷貝以便為調用樹“保持引用計數”。

<code>void my_code()
{
// cheap: 1 increment covers this entire function and all the call trees below us
auto pin = g_p;

// GOOD: passing pointer or reference obtained from a local unaliased smart pointer
f(*pin);

// GOOD: same reason
pin->func();

}/<code>

Enforcement(實施建議)

  • (Simple) Warn if a pointer or reference obtained from a smart pointer variable (Unique_pointer or Shared_pointer) that is non-local, or that is local but potentially aliased, is used in a function call. If the smart pointer is a Shared_pointer then suggest taking a local copy of the smart pointer and obtain a pointer or reference from that instead.
  • (簡單)如果函數調用時使用了一個從非局部智能指針變量(Unique_pointer or Shared_pointer)獲取的指針或者引用,報警。智能指針是局部變量但是可能是別名時也報警。如果智能指針是一個Shared_pointer,建議獲取一個智能指針的局部拷貝然後從該拷貝獲取指針或引用。

原文鏈接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r37-do-not-pass-a-pointer-or-reference-obtained-from-an-aliased-smart-pointer


覺得本文有幫助?請分享給更多人。

關注微信公眾號【面向對象思考】輕鬆學習每一天!

面向對象開發,面向對象思考!

C++核心準則R.37: 不要使用從破損的智能指針​獲取的指針或引用


分享到:


相關文章: