我目前正在开发一款在Android上使用OpenGL ES 2.0的游戏(使用NDK在C ++中)。
我有一个名为“Drawable”的类,它是使用OpenGL绘制对象的基类。 在类的析构函数中,我必须清理一些缓冲区:
Drawable::~Drawable() {
LOGE("release");
releaseBuffers();
}
但是析构函数被无休止地调用(如在线程的每个循环中),这会弄乱我的绘图。
我有点迷失在这里,我找不到类似的问题,所以欢迎帮助!
编辑:循环代码在这里:link
Edit2:我发现了一个邪恶的召唤:
在我的播放器课程中,我有这个电话:
currentWeapon->draw(this);
到
void Weapon::draw(Player* p)
如果我发表评论,垃圾邮件就会消失。
答案 0 :(得分:1)
调用析构函数的方式很少:
1)您在堆栈上创建Drawable
的实例,它超出了范围。如果这是在紧密循环中完成的,则对象将超出范围并在循环的每次迭代时被销毁。例如:
for (size_t i = 0; i < 100; ++i)
{
Drawable d;
}
此处,将在每个循环的开头和结尾创建和销毁100个Drawable
实例。
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使用“placement new”并且高度不太可能。
当对象位于诸如vector
之类的容器中时,可以在令人惊讶的时候销毁对象。考虑:
vector <Drawable> drawables;
for (size_t i = 0; i < 10000; ++i)
{
Drawable d;
drawables.push_back (d);
}
运行此代码时,您会注意到许多析构函数调用。当您push_back
时,可能会制作副本并销毁原始文件(d
)。此外,当vector
达到容量时,它必须重新分配,这会导致每个项目再次被复制,并且原件被破坏。
面对临时和意想不到的副本,对象也可以在令人惊讶的时间被销毁。考虑:
void DoSomething (Drawable d)
{
}
int main()
{
Drawable d;
for (size_t i = 0; i < 1000; ++i)
{
DoSomething (d);
}
}
这是一个天真的例子,因为在这种情况下编译器可能会忽略临时工。但由于DoSomething()
需要Drawable
按值,因此可以制作原件的副本。根据其他代码,编译器甚至可能无法忽略此副本。