是否可以在C++中自动生成析构函数?

use*_*311 9 c++ c++11

是否可以在C++中自动生成析构函数?

自己一直这样做是一个太大的负担.编译器生成析构函数是否如此困难?它不能检测什么是"资源"并在析构函数中释放它?

Mik*_*our 32

当然是,这正是语言所做的.如果你没有声明析构函数,那么将为你生成一个析构函数:它将调用每个成员和基础子对象的析构函数.

如果您正在管理未自动释放的资源,则只需编写自己的析构函数; 例如,指向您分配的内容的原始指针new.在大多数类中你不应该需要这样的东西 - 使用容器,智能指针和其他RAII类型来自动管理这些类.

  • 如果定义析构函数,编译器仍将调用每个成员和基础子对象的析构函数. (6认同)
  • @squelart在C++ 11中不再正确.你可以写`virtual~Foo()= default;`. (4认同)

Ste*_*sop 10

无法准确检测到.即使编译器观察到您在构造函数或对象的某个其他函数中分配资源,也不一定意味着它应该在析构函数中释放.这完全取决于对象是否"拥有"资源.

幸运的是,C++确实为您提供了一种方法,可以明确地通知编译器该对象拥有哪些资源.这意味着被称为"智能指针",你应该阅读的类型是shared_ptrunique_ptr.您可以通过彻底使用智能指针来避免编写析构函数.编译器生成一个销毁所有数据成员的析构函数,因此如果数据成员是智能指针,那么它们控制的资源会在适当的时候被销毁.


Joh*_*ing 5

编译器生成析构函数是否如此困难?

这不是编译器要做什么容易或困难的问题.这是C++编程基本原则问题:

你不应该为你不需要的东西买单.

这种哲学在语言设计的各个方面都占上风,包括如何定义和运行析构函数.

每个类都需要某种析构函数.这就是为什么如果你自己不这样做,编译器会自动为你写一个.这个隐式析构函数以特定的顺序和特定的方式销毁所有成员和基类.有时这不是你真正想要的,但编译器不能假设这一点.经典案例是智能指针类.智能指针类将在某处具有指向受控对象的原始指针,但编译器不知道该指针是否应为deleted - 也许您正在实现引用计数器智能指针.如果你需要析构函数实际上delete是指针,你必须自己写.

另一种情况是使用delete派生类.考虑:

Base* p = new Derived;
delete p;
Run Code Online (Sandbox Code Playgroud)

如果Derived有在它的东西一大堆需要被释放,那么你需要确保当你deleteDerived通过对象Base指针Derived的析构函数是实际上那叫一个-即使编译器无法知道的方式p实际指向a 的呼叫站点Derived.为了使这项工作,你需要做Base::~Base一个virtual析构函数.