Mik*_*our 32
当然是,这正是语言所做的.如果你没有声明析构函数,那么将为你生成一个析构函数:它将调用每个成员和基础子对象的析构函数.
如果您正在管理未自动释放的资源,则只需编写自己的析构函数; 例如,指向您分配的内容的原始指针new
.在大多数类中你不应该需要这样的东西 - 使用容器,智能指针和其他RAII类型来自动管理这些类.
Ste*_*sop 10
无法准确检测到.即使编译器观察到您在构造函数或对象的某个其他函数中分配资源,也不一定意味着它应该在析构函数中释放.这完全取决于对象是否"拥有"资源.
幸运的是,C++确实为您提供了一种方法,可以明确地通知编译器该对象拥有哪些资源.这意味着被称为"智能指针",你应该阅读的类型是shared_ptr
和unique_ptr
.您可以通过彻底使用智能指针来避免编写析构函数.编译器生成一个销毁所有数据成员的析构函数,因此如果数据成员是智能指针,那么它们控制的资源会在适当的时候被销毁.
编译器生成析构函数是否如此困难?
这不是编译器要做什么容易或困难的问题.这是C++编程的基本原则问题:
你不应该为你不需要的东西买单.
这种哲学在语言设计的各个方面都占上风,包括如何定义和运行析构函数.
每个类都需要某种析构函数.这就是为什么如果你自己不这样做,编译器会自动为你写一个.这个隐式析构函数以特定的顺序和特定的方式销毁所有成员和基类.有时这不是你真正想要的,但编译器不能假设这一点.经典案例是智能指针类.智能指针类将在某处具有指向受控对象的原始指针,但编译器不知道该指针是否应为delete
d - 也许您正在实现引用计数器智能指针.如果你需要析构函数实际上delete
是指针,你必须自己写.
另一种情况是使用delete
派生类.考虑:
Base* p = new Derived;
delete p;
Run Code Online (Sandbox Code Playgroud)
如果Derived
有在它的东西一大堆需要被释放,那么你需要确保当你delete
将Derived
通过对象Base
指针Derived
的析构函数是实际上那叫一个-即使编译器无法知道的方式p
实际指向a 的呼叫站点Derived
.为了使这项工作,你需要做Base::~Base
一个virtual
析构函数.