C++核心准则C.127:包含虚函数的类应该有虚析构函数或保护析构函...

共 2293字,需浏览 5分钟

 ·

2020-02-01 23:23

8f3f7c07e66b3af6a100671cfc9f8731.webp

独山玉雕件



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(反面示例)




struct B {
    virtual int f() = 0;
    // ... no user-written destructor, defaults to public nonvirtual ...
};

// bad: derived from a class without a virtual destructor
struct D : B {
    string s {"default"};
};

void use()
{
    unique_ptr p = make_unique();
    // ...
} // undefined behavior. May call B::~B only and leak the string

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




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

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

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

浏览 39
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报