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

时间:2014-01-09 15:13:47

标签: c++ c++11

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

自己一直这样做是太大的负担。真是太难了 为编译器生成析构函数?无法检测到什么是“资源” 并在析构函数中释放它?

4 个答案:

答案 0 :(得分:32)

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

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

答案 1 :(得分:10)

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

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

答案 2 :(得分:5)

  

编译器是否很难生成析构函数?

这不是编译器容易或难以做到的问题。这是一个 C ++编程的基本原则的问题

  

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

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

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

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

Base* p = new Derived;
delete p;

如果Derived中有大量内容需要发布,那么您需要确保delete Derived对象通过Base指针,Derived的析构函数是实际调用的 - 即使编译器无法在调用站点知道p实际指向Derived。为了完成这项工作,您需要使Base::~Base成为virtual析构函数。

答案 3 :(得分:4)

C ++和C ++ 11都没有垃圾回收。 C ++ 11确实在内存头文件中引入了许多托管指针类 - shared_ptr,weak_ptr和unique_ptr。这些旨在帮助防止内存泄漏。有关说明,请参阅MSDN上的C++ Smart Pointers教程和Smart Pointers (Modern C++)