C++核心指南(17) I.11 禁止使用指針(T*)或引用(T&)來轉移所有權

C++核心指南(17) I.11 禁止使用指針(T*)或引用(T&)來轉移所有權

I.11: 永遠不要使用原始指針(T*)或引用(T&)來轉移所有權

原因

如果對調用者或被調用者是否擁有對象有任何疑問,就會發生洩漏或過早析構。

示例

考慮:

 X* compute(args) // 不要這樣做
{
X* res = new X{};
// ...
return res;
}

誰來刪除返回的X?當compute返回一個引用時,則更難發現問題。考慮按值返回結果(如果結果很大,使用move語義):

 vector<double> compute(args) // good
{
vector<double> res(10000);
// ...
return res;
}/<double>/<double>

可選方法: 傳遞所有權 使用"智能指針",如unique_ptr(獨佔所有權)和shared_ptr(共享所有權),然而,這並不會比返回對象本身更優雅和高效,所以只有在需要引用語義時才使用智能指針。

可選方法: 有時,由於ABI的兼容性要求和資源缺失,導致更舊代碼無法修改,在這種情況下,使用指南支持庫中的owner標記擁有指針:

 owner compute(args) // 現在很清楚,所有權已經轉移
{
owner res = new X{};
// ...
return res;
}

這告訴分析工具res是所有者,也就是說,它的值必須被delete或轉移到另一個所有者,就像這裡的return所做的那樣。owner在資源句柄的實現中有也類似應用。

Note

作為原始指針(或迭代器)傳遞的每個對象都假定為調用者所擁有,因此它的生命週期由調用者處理。從另一個角度來看:與指針傳遞API相比,所有權轉移API相對較少,因此默認為“無所有權轉移”。

另請參閱: 參數傳遞、 智能指針參數的使用 和 按值返回.

實施

  • (簡單) 警告delete非owner的原始指針,建議使用標準庫資源句柄或使用owner
  • (簡單) 每條代碼路徑上reset或顯式delete一個owner指針時,警告失敗。
  • (簡單) 如果new的返回值或帶owner返回值的函數調用被分配給原始指針或非owner引用,則發出警告。


分享到:


相關文章: