前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++核心准则C.35:基类的析构函数要么是公开的虚函数,要么是保护的非虚函数

C++核心准则C.35:基类的析构函数要么是公开的虚函数,要么是保护的非虚函数

作者头像
面向对象思考
发布2020-03-25 16:03:25
9940
发布2020-03-25 16:03:25
举报

C.35: A base class destructor should be either public and virtual, or protected and nonvirtual

基类的析构函数要么是公开的虚函数,要么是保护的非虚函数

Reason(原因)

To prevent undefined behavior. If the destructor is public, then calling code can attempt to destroy a derived class object through a base class pointer, and the result is undefined if the base class's destructor is non-virtual. If the destructor is protected, then calling code cannot destroy through a base class pointer and the destructor does not need to be virtual; it does need to be protected, not private, so that derived destructors can invoke it. In general, the writer of a base class does not know the appropriate action to be done upon destruction.

为了避免无定义的行为。如果析构函数是公有的,那么调用侧的代码就会尝试使用基类指针销毁派生类的对象,在基类的析构函数为非虚函数时其结果时没有定义的。如果析构函数时保护的,那么调用侧代码就无法通过基类类型指针销毁派生类对象,这是析构函数就没有必要一定是虚函数。析构函数是保护而不是私有的,这样派生类的析构函数才能调用它。通常,基类的设计者不会知道在析构函数中应该执行什么样的动作。

Discussion(讨论)

See this in the Discussion section:参见讨论章节:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Sd-dtor.

Example, bad(反面示例)

struct Base { // BAD: implicitly has a public nonvirtual destructor virtual void f(); }; struct D : Base { string s {"a resource needing cleanup"}; ~D() { /* ... do some cleanup ... */ } // ... }; void use() { unique_ptr<Base> p = make_unique<D>(); // ... } // p's destruction calls ~Base(), not ~D(), which leaks D::s and possibly more

左右滑动查看更多

Note(注意)

A virtual function defines an interface to derived classes that can be used without looking at the derived classes. If the interface allows destroying, it should be safe to do so.

虚函数定义了派生类的接口,它可以在不关注派生类的情况下使用。如果接口允许对象,那么这个销毁过程应该是安全的。

Note(注意)

A destructor must be nonprivate or it will prevent using the type:

析构函数必须是非私有的,除了它不想被别人用。(这样可以由类自己控制销毁,译者注)

class X {

~X(); // private destructor // ... }; void use() { X a; // error: cannot destroy auto p = make_unique<X>(); // error: cannot destroy }

Exception(例外)

We can imagine one case where you could want a protected virtual destructor: When an object of a derived type (and only of such a type) should be allowed to destroy another object (not itself) through a pointer to base. We haven't seen such a case in practice, though.

我们可以想象一种需要保护的虚函数析构函数的情况:当希望允许派生类的对象(只有这个类型)通过基类指针销毁另外一个对象(不是它自己)时。但是我们还没有在实际的开发中遇到这种情况。

Enforcement(实施建议)

  • A class with any virtual functions should have a destructor that is either public and virtual or else protected and nonvirtual.
  • 拥有虚函数的类的虚函数要么是公开的虚函数,要么是保护的非虚函数。

译者注:拥有虚函数一般就意味着它有派生类。

原文链接:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-nonvirtual


觉得本文有帮助?请分享给更多人。

关注【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • To prevent undefined behavior. If the destructor is public, then calling code can attempt to destroy a derived class object through a base class pointer, and the result is undefined if the base class's destructor is non-virtual. If the destructor is protected, then calling code cannot destroy through a base class pointer and the destructor does not need to be virtual; it does need to be protected, not private, so that derived destructors can invoke it. In general, the writer of a base class does not know the appropriate action to be done upon destruction.
  • See this in the Discussion section:参见讨论章节:
  • A destructor must be nonprivate or it will prevent using the type:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档