是否可以在C ++中自动生成析构函数?
自己一直这样做是太大的负担。真是太难了 为编译器生成析构函数?无法检测到什么是“资源” 并在析构函数中释放它?
答案 0 :(得分:32)
当然是,而且这正是语言所做的。如果你没有声明析构函数,那么将为你生成一个析构函数:它将调用每个成员和基础子对象的析构函数。
如果您正在管理未自动释放的资源,则只需编写自己的析构函数;例如,指向您使用new
分配的内容的原始指针。在大多数类中你不应该需要这样的东西 - 使用容器,智能指针和其他RAII类型来自动管理它们。
答案 1 :(得分:10)
无法准确检测到。即使编译器观察到您在构造函数或对象的某些其他函数中分配资源,它也不一定遵循它应该在析构函数中释放。这完全取决于对象是否拥有"资源。
幸运的是,C ++确实为您提供了一种方法,可以明确地通知编译器该对象拥有哪些资源。这意味着被称为"智能指针",您应该阅读的类型是shared_ptr
和unique_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++)。