析构函数被连续调用

时间:2013-07-11 15:02:18

标签: c++ android-ndk opengl-es-2.0 destructor

我目前正在开发一款在Android上使用OpenGL ES 2.0的游戏(使用NDK在C ++中)。

我有一个名为“Drawable”的类,它是使用OpenGL绘制对象的基类。 在类的析构函数中,我必须清理一些缓冲区:

Drawable::~Drawable() {
LOGE("release");
releaseBuffers();
}

但是析构函数被无休止地调用(如在线程的每个循环中),这会弄乱我的绘图。

我有点迷失在这里,我找不到类似的问题,所以欢迎帮助!

编辑:循环代码在这里:link

Edit2:我发现了一个邪恶的召唤:

在我的播放器课程中,我有这个电话:

currentWeapon->draw(this); 

void Weapon::draw(Player* p)

如果我发表评论,垃圾邮件就会消失。

1 个答案:

答案 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 按值,因此可以制作原件的副本。根据其他代码,编译器甚至可能无法忽略此副本。