C++核心準(zhǔn)則C.33:如果類包含擁有所有權(quán)的指針成員,定義析構(gòu)函數(shù)

C.33: If a class has an owning pointer member, define a destructor
C.33:如果類包含擁有所有權(quán)的指針成員,定義析構(gòu)函數(shù)
Reason(原因)
An owned object must be deleted upon destruction of the object that owns it.
從屬對(duì)象必須通過擁有該對(duì)象的所有者類的析構(gòu)函數(shù)銷毀。
Example(示例)
A pointer member may represent a resource.A T* should not do so, but in older code, that's common. Consider a T* a possible owner and therefore suspect.
指針成員可能用于表達(dá)某個(gè)資源。T*不應(yīng)該這么做,但是在舊一些的代碼中,這種做法很常見??紤]到T*作為所有者使用的可能性,并確認(rèn)。
template
class Smart_ptr {
? ?T* p; ? // BAD: vague about ownership of *p
? ?// ...
public:
? ?// ... no user-defined default operations ...
};
void use(Smart_ptrp1)
{
? ?// error: p2.p leaked (if not nullptr and not owned by some other code)
? ?auto p2 = p1;}
Note that if you define a destructor, you must define or delete all default operations:
注意:一旦定義了析構(gòu)函數(shù),就必須定義或者禁止所有的默認(rèn)操作。
譯者注:這里的默認(rèn)操作指的是默認(rèn)構(gòu)造函數(shù),拷貝/移動(dòng)構(gòu)造函數(shù),拷貝/移動(dòng)運(yùn)算符和析構(gòu)函數(shù)。template
class Smart_ptr2 {
? ?T* p; ? // BAD: vague about ownership of *p
? ?// ...
public:
? ?// ... no user-defined copy operations ...
? ?~Smart_ptr2() { delete p; } ?// p is an owner!
};
void use(Smart_ptr2 p1)
{
? ?auto p2 = p1; ? // error: double deletion
} The default copy operation will just copy the p1.p into p2.p leading to a double destruction of p1.p. Be explicit about ownership:
默認(rèn)拷貝操作只是將p1.p的值賦給p2.p(不包含其指向?qū)ο蟮目截悾@會(huì)導(dǎo)致p1.p的雙重析構(gòu)。明確所有權(quán):
template
class Smart_ptr3 {
? ?owner p; ? // OK: explicit about ownership of *p
? ?// ...
public:
? ?// ...
? ?// ... copy and move operations ...
? ?~Smart_ptr3() { delete p; }
};
void use(Smart_ptr3 p1)
{
? ?auto p2 = p1; ? // OK: no double deletion
}
譯者注:實(shí)際上并不是改變p的類型為owner就可以解決問題的。注意這段代碼通過注釋實(shí)現(xiàn)了拷貝和移動(dòng)操作,而前一段代碼沒有。*>
Note(注意)
Often the simplest way to get a destructor is to replace the pointer with a smart pointer (e.g., std::unique_ptr) and let the compiler arrange for proper destruction to be done implicitly.
一般來說,得到析構(gòu)函數(shù)最簡(jiǎn)單的方式是將指針換成智能指針(例如std::unique_ptr)并且讓編譯器提供適當(dāng)?shù)碾[式執(zhí)行的析構(gòu)動(dòng)作。
Note(注意)
Why not just require all owning pointers to be "smart pointers"? That would sometimes require non-trivial code changes and may affect ABIs.
為什么不簡(jiǎn)單地要求所有的所有者指針都變成“智能指針”?因?yàn)槟菢幼鲇袝r(shí)會(huì)引起重大的代碼變更并且影響二進(jìn)制接口。
Enforcement(實(shí)施建議)
A class with a pointer data member is suspect.
帶有指針類型數(shù)據(jù)成員的類都是可疑的。
A class with an owner
should define its default operations. 擁有owner
成員的類應(yīng)該定義默認(rèn)操作。
譯者注:owner的定義就是T,只是在源代碼層次上增加了信息量,方便讀者理解和工具檢查。編譯器看起來和之前的T沒有任何區(qū)別,因此在二進(jìn)制生成物層面上沒有變化,這樣就保證了既有代碼可以安全地引入這種做法。
原文鏈接:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c33-if-a-class-has-an-owning-pointer-member-define-a-destructor
覺得本文有幫助?請(qǐng)分享給更多人。
關(guān)注【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
