【问题标题】:How to call the destructor of a child of an abstract class?如何调用抽象类的子类的析构函数?
【发布时间】:2020-08-25 18:48:58
【问题描述】:

我有一个纯抽象类:

class Abstract{
     void func1(arg1, arg2) = 0;
}

及其使用析构函数的实现:

class Concrete : public Abstract{
void func1(arg1,arg2) { /*implementation code..*/ };
~Concrete() {/*code for the destructor..*/}

在 main.cpp 中,我为它创建了一个唯一的指针:

 int main(){
 std::unique_ptr<Abstract> class = std::make_unique<Concrete>();
 //do operations with it
 class.reset();
 }

完成class 后,我需要它调用当前implementation class 的(自定义)析构函数,但.reset() 不这样做。如何调用Abstract类的这个实现的析构函数?

【问题讨论】:

  • 你需要在基类上声明和定义一个虚析构函数。它可能是空的,但它需要存在,以便在销毁时,可以找到并调用适当的析构函数。 stackoverflow.com/questions/270917/…
  • 然后.reset() 会起作用吗?
  • 重置会导致对象的定期销毁。如果一个对象有一个虚拟析构函数,这将导致派生的析构函数被调用。简而言之,是的。
  • @Evg 确实如此,但如果您在基类中没有受保护/私有析构函数,我会认为这是不好的设计。此外,我不会以此为理由在 unique_ptrshared_ptr 之间进行选择,因为它们有不同的用途。
  • 不应该Concrete继承自Abstract吗?

标签: c++ interface virtual destructor unique-ptr


【解决方案1】:

根据您的实现,您尚未将 Abstract Class Destructor 定义为虚拟。

如此简单的解决方法是将destructor 设为Abstract Class 作为virtual

所以抽象类的声明如下所示:

class Abstract{
     public:
     void func1(arg1, arg2) = 0;
     virtual ~Abstract() {/*..Destrctor Body..*/}
}

现在出现的原因是在 main.cpp 中,您使用 pointer of the Abstract Class 指向 Concrete Class 的对象,并且您在 Abstract 的指针上执行了 reset() class ,它将导致destructor of only Abstract class 被调用。

但是一旦你创建了 destructor of the Abstract Class as Virtual ,它就会调用具体类的 **destructor **First****,然后再调用 destructor of the Abstract Class

更多细节我分享一个线程供参考When Should we Use Virtual keyword ?

【讨论】:

  • 回复:“......它会导致只调用抽象类的析构函数”——比这更糟糕。行为未定义。语言定义对该代码的功能没有任何要求。实际上,您是对的,但编译器不需要这样做。 +1。
猜你喜欢
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多