【问题标题】:Clarifying trivial destructors澄清琐碎的析构函数
【发布时间】:2020-11-19 20:58:30
【问题描述】:

来自 IBM.com (https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzarg/cplr380.htm)

如果满足以下所有条件,则 A 类的析构函数是微不足道的:

  1. 它是隐式定义的
  2. A 的所有直接基类都有微不足道的析构函数
  3. 如果满足以下所有条件,A 的所有非静态数据成员的类都具有平凡的析构函数 A 类的析构函数是平凡的(不是必需的):

解释:

  1. 类中使用的构造函数已导入。类中没有创建新的构造函数。

  2. 来自网站:“直接基类是在其派生类的声明中直接作为基说明符出现的基类。”当我想知道什么是基本说明符时,兔子洞仍在继续。请帮忙。

  3. 数据类型是原始的。

如果我的任何解释有误或为了清楚起见可以进一步简化,请发表评论。

class Foo {
public:
    ~Foo() { s = “”; x = 0; vi.clear(); }
private:
    string s;
    int x;
    vector<int> vi;
};

鉴于创建如上所示的析构函数被认为是一种不好的做法,是否有一种简单的方法可以记住何时需要创建析构函数?

【问题讨论】:

  • 如果类的成员拥有(负责)在类被破坏时不会自动释放的资源,则需要一个析构函数。 (例如,如果持有拥有原始指针,其他资源由该类分配和拥有)或者它是一个像树一样的结构,其中破坏可能导致大量递归析构函数调用,这可能导致堆栈溢出。
  • 目前尚不清楚您问题的哪一部分是来自 ibm.com 的逐字引用。能否请您 (1) 使用适当的标记 (&gt; …) 将直接引用标记为此类,以及 (2) 包含引用引用来源的链接?
  • 希望我更正了不清楚的报价并给出了正确的相应链接!

标签: c++ default destructor


【解决方案1】:

零规则(来自cppreference):

具有自定义析构函数、复制/移动构造函数或复制/移动赋值运算符的类应专门处理所有权(遵循单一责任原则)。其他类不应有自定义析构函数、复制/移动构造函数或复制/移动赋值运算符。

我喜欢 cppreference 非常明确的方式。

要么编写一个只管理资源的类。在这种情况下,您确实需要阅读 3/5 规则(相同链接)。这应该很少见,因为已经有容器和智能指针为您管理资源。然而,应该启用 RAII 的“资源”不仅可以是内存,还可以是文件、数据库连接等。

或者你编写一个不管理资源的类。在这种情况下,您不需要编写析构函数。

【讨论】:

  • Or you write a class the does not manage a resource. In that case you do not need to write a destructor. 这大部分是正确的。正如我在评论中所写,有一个例外——取决于你如何定义管理资源——一个例外,如果将在树状结构中完成的自动销毁导致大量递归销毁调用,则可能导致堆栈溢出,那么你应该——即使资源会被自动删除——创建一个析构函数,以更好的方式释放资源。
  • @t.niese 在写完答案后我意识到它只是将问题延迟到“管理资源意味着什么?”并且圈子通过声明“一个类在需要在析构函数中释放它时管理资源”来结束。不确定,但也许您的案例可以被视为“除了管理资源什么都不做”,因为这基本上就是一棵树对其节点所做的事情。无论如何,“简单规则”总会有例外
猜你喜欢
  • 2010-10-01
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
相关资源
最近更新 更多