-1

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

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

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

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

我有点迷路了,我找不到类似的问题,所以欢迎帮助!

编辑:循环代码在这里:链接

Edit2:我发现了一个邪恶的电话:

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

currentWeapon->draw(this); 

void Weapon::draw(Player* p)

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

4

1 回答 1

1

调用析构函数的方法很少:

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

于 2013-07-11T15:10:06.457 回答