C++核心准则C.31:类请求的所有资源必须在析构函数释放

面向对象思考

共 2721字,需浏览 6分钟

 ·

2019-12-21 23:21

9506a53dece06991121bc2f826ae91b0.webp

C.31: All resources acquired by a class must be released by the class's destructor

类申请的所有资源必须在析构函数释放


Reason(原因)

Prevention of resource leaks, especially in error cases.

避免资源泄露,特别是在发生错误的情况下。


Note(注意)

For resources represented as classes with a complete set of default operations, this happens automatically.

如果资源表现为实现了全套默认操作的类,这些会自动发生。


Example(示例)
class X {    ifstream f;   // may own a file    // ... no default operations defined or =deleted ...};

X's ifstream implicitly closes any file it may have open upon destruction of its X.

X类的ifstream成员通过析构函数隐式关闭任何它打开的任何文件。


Example, bad(反面示例)
class X2 {     // bad    FILE* f;   // may own a file    // ... no default operations defined or =deleted ...};

X2 may leak a file handle.

X2存在泄露文件句柄的可能性。(具体讲通常是漏掉关闭文件,译者注)


Note(注意)

What about a sockets that won't close? A destructor, close, or cleanup operation should never fail. If it does nevertheless, we have a problem that has no really good solution. For starters, the writer of a destructor does not know why the destructor is called and cannot "refuse to act" by throwing an exception. See discussion. To make the problem worse, many "close/release" operations are not retryable. Many have tried to solve this problem, but no general solution is known. If at all possible, consider failure to close/cleanup a fundamental design error and terminate.

sokcet(通信,译者注)没有被关闭会怎么样?首先,析构函数,关闭或清除操作永远不应该失败。如果它确实会失败,这问题还没有真正好的解决方案。对于(通信,译者注)起始模块,析构函数的作者并不知道析构函数因为什么被调用,而且没有办法通过抛出异常来“拒绝处理”。参见讨论(https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Sd-never-fail)。更为严重的是,许多“关闭/释放”操作都无法重试。为了解决这个问题有过许多尝试,不是没有找到通用的解决方案。如果可能,可以将关闭或清除的失败看作根本性错误并终止。


Note(注意)

A class can hold pointers and references to objects that it does not own. Obviously, such objects should not be deleted by the class's destructor. For example:

类可以持有指向那些它并不拥有所有权的对象的指针或引用。显然,这样的对象不应该被该类的析构函数销毁。例如:

Preprocessor pp { /* ... */ };Parser p { pp, /* ... */ };Type_checker tc { p, /* ... */ };

Here p refers to pp but does not own it.

这里p指向了pp但是并不拥有pp。


Enforcement(实施建议)

  • (Simple) If a class has pointer or reference member variables that are owners (e.g., deemed owners by using gsl::owner), then they should be referenced in its destructor.

    (简单)如果类包含具有所有权(例如通过gsl::owner宣示所有权)的指针或引用成员,则它们应该在析构函数中被引用。

    译者注:个人觉得应该是在析构函数中释放。

  • (Hard) Determine if pointer or reference member variables are owners when there is no explicit statement of ownership (e.g., look into the constructors).

  • (困难)在指针或引用类型的成员变量没有明确陈述所有权时判断它们是否是所有者(例如通过走查构造函数等方式)。


原文链接:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c31-all-resources-acquired-by-a-class-must-be-released-by-the-classs-destructor




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

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

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

浏览 15
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

举报