调用析构函数的方法很少:
1)您在堆栈上创建了一个实例Drawable
,但它超出了范围。如果这是在紧密循环中完成的,则对象将超出范围并在循环的每次迭代中被销毁。例如:
for (size_t i = 0; i < 100; ++i)
{
Drawable d;
}
Drawable
在这里,将在每个循环的开始和结束时创建和销毁100 个实例。
2)您delete
是动态分配的Drawable
:
for (size_t i = 0; i < 100; ++i)
{
Drawable* d = new Drawable;
delete drawable;
}
3)你显式调用析构函数:
Drawable* b = new (buffer) Drawable;
b->~Drawable()
请注意,#3 使用“新位置”并且不太可能。
当对象位于诸如vector
. 考虑:
vector <Drawable> drawables;
for (size_t i = 0; i < 10000; ++i)
{
Drawable d;
drawables.push_back (d);
}
运行此代码时,您可能会注意到许多析构函数调用。当 you 时push_back
,可能会制作一份副本,而原件(d
此处)将被销毁。此外,当vector
达到容量时,它必须重新分配,这导致每个项目都被再次复制,并且原件被销毁。
面对临时和意外的副本,对象也可能在惊人的时间被破坏。考虑:
void DoSomething (Drawable d)
{
}
int main()
{
Drawable d;
for (size_t i = 0; i < 1000; ++i)
{
DoSomething (d);
}
}
这是一个幼稚的例子,因为在这种情况下编译器可能会忽略临时变量。但是由于DoSomething()
采用了Drawable
按值计算,因此可以制作原件的副本。根据其他代码,编译器甚至可能无法删除此副本。