01.31 C++核心準則C.127:包含虛函數的類應該有虛或保護析構函數

C++核心準則C.127:包含虛函數的類應該有虛或保護析構函數

獨山玉雕件

C.127: A class with a virtual function should have a virtual or protected destructor

C.127:包含虛函數的類應該有虛析構函數或保護析構函數‍

Reason(原因)

A class with a virtual function is usually (and in general) used via a pointer to base. Usually, the last user has to call delete on a pointer to base, often via a smart pointer to base, so the destructor should be public and virtual. Less commonly, if deletion through a pointer to base is not intended to be supported, the destructor should be protected and nonvirtual; see C.35.

包含虛函數的類通常(大多數情況下)通過指向基類的指針使用。通常,最有一個使用者必須通過指向基類的指針調用delete操作,通常是指向基類的智能指針,因此析構函數應該是公開的虛函數。稍微特殊一些的情況是:如果不希望支持通過指向基類的指針銷燬對象,析構函數應該是保護的非虛函數。參見C.35。

Example, bad(反面示例)

<code>structB{
virtualintf()=0;
//...nouser-writtendestructor,defaultstopublicnonvirtual...
};

//bad:derivedfromaclasswithoutavirtualdestructor
structD:B{
strings{"default"};
};

voiduse()

{
unique_ptrp=make_unique();
//...
}//undefinedbehavior.MaycallB::~Bonlyandleakthestring
/<code>

Note(注意)

There are people who don't follow this rule because they plan to use a class only through a shared_ptr: std::shared_ptr p = std::make_shared(args); Here, the shared pointer will take care of deletion, so no leak will occur from an inappropriate delete of the base. People who do this consistently can get a false positive, but the rule is important -- what if one was allocated using make_unique? It's not safe unless the author of B ensures that it can never be misused, such as by making all constructors private and providing a factory function to enforce the allocation with make_shared.

也有一些人計劃只通過shared_ptr使用類:std::shared_ptr p=std::make_shared(args);這段代碼中共享指針會負責對象的銷燬,因此不會因為不適當的銷燬調用而引起內存洩露。一直這麼做的人會產生一個錯誤的判斷,但是準則還是重要的--如果某人使用make_unique申請內存會怎麼樣?這種做法不夠安全,除非B的生成者可以確保它永遠不會被誤用,例如通過讓所有的構造函數都私有而且提供一個工廠方法保證所有的內存分配都通過make_shared進行。

Enforcement(實施建議)

  • A class with any virtual functions should have a destructor that is either public and virtual or else protected and nonvirtual.
  • 包含虛函數的類的析構函數要麼是公開的虛函數,要麼是保護的非虛函數。
  • Flag delete of a class with a virtual function but no virtual destructor.
  • 提示針對包含虛函數卻沒有虛析構函數的類的銷燬操作。

原文鏈接:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#enforcement-123


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

更多精彩文章請關注微信公眾號【面向對象思考】!

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


分享到:


相關文章: