前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++核心准则C.33:如果类包含拥有所有权的指针成员,定义析构函数

C++核心准则C.33:如果类包含拥有所有权的指针成员,定义析构函数

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

C.33: If a class has an owning pointer member, define a destructor

C.33:如果类包含拥有所有权的指针成员,定义析构函数

Reason(原因)

An owned object must be deleted upon destruction of the object that owns it.

从属对象必须通过拥有该对象的所有者类的析构函数销毁。

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.

指针成员可能用于表达某个资源。T*不应该这么做,但是在旧一些的代码中,这种做法很常见。考虑到T*作为所有者使用的可能性,并确认。

代码语言:javascript
复制
template<typename T>
class Smart_ptr {
    T* p;   // BAD: vague about ownership of *p
    // ...
public:
    // ... no user-defined default operations ...
};

void use(Smart_ptr<int> p1)
{
    // 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:

注意:一旦定义了析构函数,就必须定义或者禁止所有的默认操作。

译者注:这里的默认操作指的是默认构造函数,拷贝/移动构造函数,拷贝/移动运算符和析构函数。

代码语言:javascript
复制
template<typename T>
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<int> 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:

默认拷贝操作只是将p1.p的值赋给p2.p(不包含其指向对象的拷贝),这会导致p1.p的双重析构。明确所有权:

代码语言:javascript
复制
template<typename T>
class Smart_ptr3 {
    owner<T*> p;   // OK: explicit about ownership of *p
    // ...
public:
    // ...
    // ... copy and move operations ...
    ~Smart_ptr3() { delete p; }
};

void use(Smart_ptr3<int> p1)
{
    auto p2 = p1;   // OK: no double deletion
}

译者注:实际上并不是改变p的类型为owner就可以解决问题的。注意这段代码通过注释实现了拷贝和移动操作,而前一段代码没有。

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.

一般来说,得到析构函数最简单的方式是将指针换成智能指针(例如std::unique_ptr)并且让编译器提供适当的隐式执行的析构动作。

Note(注意)

Why not just require all owning pointers to be "smart pointers"? That would sometimes require non-trivial code changes and may affect ABIs.

为什么不简单地要求所有的所有者指针都变成“智能指针”?因为那样做有时会引起重大的代码变更并且影响二进制接口。

Enforcement(实施建议)

  • A class with a pointer data member is suspect. 带有指针类型数据成员的类都是可疑的。
  • A class with an owner<T> should define its default operations. 拥有owner<T>成员的类应该定义默认操作。

译者注:owner的定义就是T,只是在源代码层次上增加了信息量,方便读者理解和工具检查。编译器看起来和之前的T没有任何区别,因此在二进制生成物层面上没有变化,这样就保证了既有代码可以安全地引入这种做法。

原文链接:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c33-if-a-class-has-an-owning-pointer-member-define-a-destructor


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

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

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • An owned object must be deleted upon destruction of the object that owns it.
  • 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.
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档