在 Accelerated C++ 第 11 章中,作者提出了一个使用数组模拟 std::vector 行为的 Vector 类。他们使用分配器类来处理内存管理。的作用uncreate
函数是销毁数组的每个元素并释放为数组分配的空间:
template <class T> void Vec<T>::uncreate() {
if (data) {
// destroy (in reverse order) the elements that were constructed
iterator it = avail;
while (it != data)
alloc.destroy(--it);
// return all the space that was allocated
alloc.deallocate(data, limit - data);
}
// reset pointers to indicate that the Vec is empty again
data = limit = avail = 0;
}
显然我们需要释放已分配的空间。但我不清楚为什么我们也需要销毁单个元素。如果我们只释放内存而不破坏单个元素,会发生什么?
原因是它可能会给你带来麻烦。 C++标准第3.8章(对象生命周期)的第4段解释了原因(强调我的):
程序可以通过重用对象占用的存储空间或显式地结束任何对象的生命周期
使用非平凡的析构函数调用类类型的对象的析构函数。对于类类型的对象
使用非平凡的析构函数,程序不需要在存储之前显式调用析构函数
对象占用的空间被重用或释放;然而,如果没有显式调用析构函数或者如果
删除表达式(5.3.5)不用于释放存储,析构函数不得被隐式调用
任何依赖于析构函数产生的副作用的程序都有未定义的行为。
这意味着可以在具有简单析构函数(*)的对象或根本没有析构函数的对象(例如ints
等)。但是,当内存包含需要在析构函数中执行某些操作(例如关闭网络连接或文件、刷新缓冲区、释放内存)的类的对象时,您将泄漏资源(并且按照标准,正式调用未定义的行为)。
(*) 如果析构函数是由编译器生成的,不是虚拟的,并且它所属的类的所有非静态成员和直接基类都具有平凡的析构函数,则该析构函数是平凡的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)