【问题标题】:Should an abstract class' destructor be pure virtual?抽象类的析构函数应该是纯虚拟的吗?
【发布时间】:2011-03-31 00:07:55
【问题描述】:

我认为通常单独使用虚拟就足够了。

除了强制派生类实现自己的析构函数之外,还有其他理由让它成为纯虚拟吗?我的意思是,如果你在类的构造函数中分配了一些东西,你应该实现你自己的析构函数 -类是否派生。

据我所知,这不算作答案:如果你想要你的类抽象并且它没有纯虚函数 - 把它留给析构函数。

还有什么用途?

【问题讨论】:

  • 请注意,如果没有明确提供,编译器会自动在派生类中生成析构函数。这个自动生成的析构函数就够了,不用你自己写析构函数,即使基类里的那个是纯的。
  • 所以即使是第一个原因实际上也没有。很棒的评论!
  • 附注:另一个必须是虚拟的函数是(如果存在)operator=。与 dtor 的原因相同。
  • @rursw1: operator=() 对具有值语义的类很有用,但对多态类没有用。

标签: c++ abstract-class destructor pure-virtual


【解决方案1】:

没有。如果基类分配了任何东西,则有责任释放它。

此外,如果派生类没有分配任何东西,那么强迫他们编写一个虚拟 dtor 是没有意义的。

【讨论】:

  • 你不会强迫他们做任何事情。如果他们没有定义析构函数,编译器会为他们做。
  • @Tadeusz:哪怕是基地里的纯虚拟?
  • 是的 - 使用 gcc 3.4.5 测试。问题:符合 C++ 标准吗?
  • 另外,第一点无关紧要;基类析构函数必须有一个实现,即使它是纯虚拟的。
  • 标准 12.4.7 "析构函数可以声明为虚拟 (10.3) 或纯虚拟 (10.4);如果在程序中创建了该类或任何派生类的任何对象,则应定义析构函数. 如果一个类有一个带有虚拟析构函数的基类,那么它的析构函数(无论是用户声明的还是隐式声明的)都是虚拟的。”
【解决方案2】:

如果您的抽象类是一个纯接口,没有数据成员,那么您可以将 dtor 设为纯虚拟。我自己更喜欢这样,因为我见过很多炙手可热的程序员根本忘记创建虚拟析构函数:即使他们编写包含虚拟方法的派生类也是如此。 所以我会这样做纯粹是为了尽量减少以后的维护麻烦。

【讨论】:

  • 忘记编写析构函数在任何类中都是一种风险,而不仅仅是派生类!这里最大的问题是忘记在 base 类中编写虚拟析构函数。
  • 我不知道为什么会有反对票?因为没有关于原因的cmets。所以这不是很有帮助 - 如果我错过了什么。或者如果我没有很好地表达自己(我知道今天早上我可以使用校对器)。
【解决方案3】:

理想情况下,语言应该有一种方法来确保(隐式或不隐式地)析构函数在抽象类中是虚拟的,而不必定义它或使其纯粹。但它没有。

所以选择是:要么让它成为纯粹的,并有责任在每个派生类中定义它,要么不让它成为纯粹的,并有责任在抽象类中定义它。后者工作量少,代码也更短,所以我会去。

【讨论】:

  • 代码更短,因为纯虚拟 dtor 必须在类外实现。反对纯虚拟的第一个论点!谢谢
  • 实际上,我不认为代码会变短。比较~Klass() =0 + 它的实现和~Klass() {}
  • "+ its implementation" 是关键,因为它不能内联,即 Klass::~Klass(){}
  • @jpalacek,我的意思是,如果析构函数在抽象类中不是纯的,则不必在每个派生类中定义它。所以你在调用链中没有额外的析构函数。派生类也不会那么混乱。
  • @Fabio:即使它在基类中是纯的,您也不必在每个派生类中定义它。隐式析构函数已经足够好了。
【解决方案4】:

如果你想要你的类摘要并且它 没有纯虚函数——离开 把它交给析构函数。

实际上,我不认为还有更多。纯虚析构函数所做的就是使整个类抽象。您必须为纯虚拟析构函数和非纯虚拟析构函数提供实现,派生类的析构函数是虚拟的,只有虚拟析构函数,等等。

基本上,如果一个类已经有一些纯虚函数,它的行为将等同于虚和纯虚析构函数。

【讨论】:

  • 确实是答案,最符合我的问题。
猜你喜欢
  • 2019-04-20
  • 2011-03-21
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-05
  • 2023-03-23
  • 2011-10-25
相关资源
最近更新 更多