【问题标题】:Is it good practice to write constructor/destructor?编写构造函数/析构函数是一种好习惯吗?
【发布时间】:2019-02-01 12:42:31
【问题描述】:

我想知道即使我不使用它们,总是编写构造函数/析构函数是否是一个好习惯。

class Foo
{
public:
    Foo(){};
    ~Foo(){};
};

或者只有在我实际使用它们时才编写它们是更好的做法?

class Foo
{
public:
};

【问题讨论】:

  • 请注意,声明一个虚拟析构函数将强制您的类的每个对象包含一个 vtable 指针,每创建一个 Foo 就会将其内存使用量增加一个字(例如 8 个字节)。因此,如果您知道您的 Foo 类永远不会使用虚拟方法(和/或永远不会被使用虚拟方法的子类继承),那么不声明虚拟析构函数(声明非虚拟析构函数)是有好处的虽然不会增加内存使用量)。 OTOH,如果您知道对象将使用虚拟方法,那么声明虚拟析构函数是个好主意。
  • 堆栈溢出不适用于意见问题。
  • @xaxxon “主要基于意见的问题”和“其答案将包含一些意见的问题”之间存在差异。 “主要”是关键字。
  • @xaxxon 但问题不是征求意见,OP 可能没有意识到这是一个意见问题。一个合理的答案可能是“这是一个见仁见智的问题;有些人这样做是因为___,而另一些人认为这是不必要的,因为___。”很多好的和有效的问题都是这样的。该指南的目的是防止问题变成辩论。
  • @xaxxon:这不是对最佳实践的开放式请求,它提供了两个选项,并询问这两个中的哪个更好。具有基于事实的答案的问题。仅仅因为您想到了基于意见的答案,并不会使所有其他答案或问题本身都基于意见。

标签: c++ class constructor destructor


【解决方案1】:

当默认成员函数足够时,用户定义特殊成员函数是个坏主意。

  • 您将失去默认生成的移动操作,请参阅Does a default virtual destructor prevent compiler-generated move operations?

  • 您的类将不再是微不足道的,导致分配和释放以及容纳您的类的容器效率大大降低。

  • 默认定义可能自动为noexcept,但您丢失了它。

  • 您的类不再是聚合,因此不能使用聚合初始化。

  • 如果您将析构函数设为虚拟,如您的问题所示,您也会失去标准布局。

【讨论】:

  • 此外,根据 ABI,可简单复制的类型可以更有效地传递给函数(在寄存器中而不是在堆栈中传递)。
  • 不是。我不是在谈论 c++ 语言规范,而是在 itanium c++ ABI 中描述的调用约定。
  • @Oliv:规范的规则限制了调用约定。只有当规范和 ABI 都允许时,变量才能存在于寄存器中并且没有内存地址。
猜你喜欢
  • 2017-10-11
  • 2021-04-11
  • 2018-12-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
相关资源
最近更新 更多