如何对动态数组中的某些对象调用析构函数
how to call destructor on some of the objects in a Dynamic Array
我终于开始尝试放置新来创建高效的动态数组。 目的是了解它是如何工作的,而不是替换类向量。 构造函数工作。已分配块但未初始化。添加每个元素时,都会对其进行初始化。但是我不明白如何使用放置删除来仅对存在的元素调用析构函数。谁能解释一下?此代码用于随着数组的增长逐个分配元素,但删除不正确。
template<typename T>
class DynArray {
private:
uint32_t capacity;
uint32_t size;
T* data;
void* operator new(size_t sz, T* place) {
return place;
}
void operator delete(void* p, DynArray* place) {
}
public:
DynArray(uint32_t capacity) :
capacity(capacity), size(0), data((T*)new char[capacity*sizeof(T)]) {}
void add(const T& v) {
new(data+size++) T(v);
}
~DynArray() {
for (int i = 0; i < size; i++)
delete (this) &data[i];
delete [] (char*)data;
}
};
放置
delete
没有多大意义,因为析构函数已经执行了放置delete
应该执行的操作。
普通delete
调用析构函数,然后释放使用 new
为对象分配的内存。然而,与普通new
不同,放置new
不分配内存,它只初始化内存。因此,放置delete
只需调用要"删除"对象的析构函数。
您所需要的只是直接调用数组中每个对象的析构函数:
~DynArray() {
for (int i = 0; i < size; i++)
data[i].~T();
}
从 C++17 开始,您还可以std::destroy
使用函数模板,而不是直接调用析构函数:
~DynArray() {
auto first = std::addressof(data[0]);
auto last = std::next(first, size);
std::destroy(first, last);
}
您实际上找到了想要手动调用析构函数的唯一情况(至少我知道
(: ~DynArray() {
for (int i = 0; i < size; i++)
data[i].~T();
delete [] (char*)data;
}
结合一个简单的类和main
,你应该得到预期的结果:
struct S {
~S() { std::cout << __PRETTY_FUNCTION__ << 'n'; }
};
int main() {
DynArray<S> da{10};
da.add(S{});
return 0;
}
请注意,您会看到析构函数被调用两次,因为DynArray
通过引用const
获取对象,因此它具有临时函数。
$./a.out
S::~S()
S::~S()
相关文章:
- 对RValue对象调用的LValue ref限定成员函数
- 检查哪个对象调用了另一个对象的对象方法
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 从 Base 引用对象调用派生类的成员
- 为什么为未删除的对象调用析构函数?
- Qt c++不会为所有对象调用move_slot.为什么?
- 使用在堆栈上创建的对象调用虚拟函数
- 使用基类对象调用Dervied Class函数
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 从类中的对象调用类中的函数的最佳方法
- 派生对象调用的 Base 方法的模板推导
- 如何使用单个对象调用具有相同名称的两个类函数
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 如果类没有任何成员变量,则通过临时对象调用类的成员函数的开销是多少?
- 如何对动态数组中的某些对象调用析构函数
- 如何从列表中存储的对象调用成员函数
- 从线程内的对象调用静态方法
- 从成员对象调用方法
- 当包含它的对象调用其析构函数时,unique_ptr是否未分配
- 从对象调用成员对象,错误:引用非常量值的初始值必须是左值