删除类内成员函数中的对象

时间:2013-06-12 19:40:51

标签: c++ class object this delete-operator

我正在开发一款游戏,我有一个树类。这个类有一个名为“wood”的int,它可以保留树木中留下的木材数量。还有一个功能可以跟踪所有事件。当值达到零时,我想删除此对象。(顺便说一句,我使用的是CodeBlocks和SDL库)

handle_events函数:

void Tree::handle_events(SDL_Event event, int MouseX, int MouseY, int Xoffset, int Yoffset) {
if(event.type == SDL_MOUSEBUTTONDOWN) {
    if( event.button.button == SDL_BUTTON_LEFT ) {

        if((MouseX >= (xPos - Xoffset)) && (MouseX <= ((xPos + 50) - Xoffset)) && (MouseY >= (yPos - Yoffset)) && (MouseY <= ((yPos + 50) - Yoffset))) {
            selected = true;
        } else {
            selected = false;
        }
    }
}

if(wood <= 0) {
    delete this;
}

}

当我启动游戏并且“木头”变为零时,树仍在那里工作。 请帮忙

编辑:

while(SDL_PollEvent(&event)) {
        MouseX = event.motion.x;
        MouseY = event.motion.y;

        menu_button.handle_button_events(event, MouseX, MouseY);
        exit_button.handle_button_events(event, MouseX, MouseY);

        for(int i = 0; i < trees.size(); i++)
        {
            trees[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset);
        }

        for(int i = 0; i < stones.size(); i++)
        {
            stones[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset);
        }

        for(int i = 0; i < bushes.size(); i++)
        {
            bushes[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset);
        }

        if(event.type == SDL_QUIT) {
            running = false;
        }

        if(event.type == SDL_KEYDOWN) {
            switch(event.key.keysym.sym) {
            case SDLK_ESCAPE:
                running = false;
            }
        }

        if(exit_button.clicked) {
            running = false;
        }

        if(menu_button.clicked) {
            paused = true;
        }


    }

树是一个包含地图上所有树木的向量

2 个答案:

答案 0 :(得分:2)

trees中的trees[i]是什么?我认为它是std::vector<Tree*>或类似的?

当您致电delete this时,您正在删除trees[i]引用的对象,但您没有删除该向量中的条目。删除后trees[i]指向一些释放的内存 - 如果没有被其他内容覆盖 - 仍然看起来像树对象。

我建议做这样的事情:

for(int i = trees.size()-1; i >= 0; i--) {
    trees[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset);
    if (trees[i].isEmpty()) {
        delete trees[i];
        trees.erase(trees.begin()+i);
    }
}

注意,从末尾开始迭代非常重要,因为当删除元素时,所有后续操作都将被移位。

如果向量很大并且您进行了大量删除,请考虑使用不提供随机访问的不同结构,因为从向量中删除可能非常耗时。


<强>更新 我假设成员函数Tree::isEmpty()由您实现,其逻辑指定对象何时为空且不再需要,但实际上没有删除对象。

正如你所说,treesTree个对象的向量,而不是指针,你应该从不自己删除这些对象!向量是这些对象的所有者,它将删除它们。

因此,您应该致电trees.erase(trees.begin()+i)并放弃该对象。

答案 1 :(得分:1)

delete this实际上并不清理对象仍然存在的指针。 (它确实调用了析构函数 - 但是因为你有一个空的析构函数,所以也没有在这里完成这样的清理。)在你delete this之后,仍然会有一个(悬空!)指针指向已删除的树。 trees向量。

使用此指针的一个可能结果是树仍然出现,另一种可能是崩溃。没有办法只使用指针来指示来自有效指针的悬空指针。

出于这个原因,delete this通常是一个坏主意,从来不是一个简单的解决方案。

您可以考虑从调用handle_events()的函数中检查树是否已用完木材 - 然后您既可以删除树,也可以从向量中删除指针。