gpt4 book ai didi

c++ - 实现 "window"系统和 "no deletion of self"规则

转载 作者:行者123 更新时间:2023-11-30 01:59:59 25 4
gpt4 key购买 nike

我一直在尝试用 C++ 编写一种用于游戏的简单“窗口”系统,它在游戏区域(游戏自身的图形内部,即不是操作系统的 GUI 窗口)。窗口对象(这里称之为“类 Window”)有一些事件方法,如按键,以及 Hook 处理程序的能力,以便在收到该事件时调用。

Windows 被(或将被)收集在“窗口管理器”中,并且窗口对象将具有“close()”成员,该成员将调用父窗口管理器的窗口删除例程来删除自身。一个事件处理程序,比如说,一个窗口上的按钮可能会调用这个例程来关闭窗口(想想一个“确定”框)。

问题是这听起来像“delete *this;”语句,我听说这是一个不-不。没错,它不是直接那样做的,但效果是一样的:一个对象有一个成员函数,它带来了它自己的破坏(例如“close()”函数,或事件函数触发导致调用“close()”函数的处理程序。)。如果这很糟糕,那么更好的设计方法是什么?

最佳答案

对象删除自身并没有错。您必须简单地告诉窗口管理器从它的集合中删除窗口然后删除。如果您让窗口管理器删除窗口对象,那就更好了。

如果您真的想避免这种行为,您可以向每个初始化为 false 的窗口添加一个 bool dead;。当窗口要关闭时,设置this->dead = true;。每一帧,让窗口管理器遍历它的窗口并删除死掉的窗口。

请注意,此解决方案仍然无法修复引用已删除窗口的外部系统引起的错误,但它确实具有集中删除窗口的优势。

我设计过很多游戏的窗口系统,根据我的经验,允许窗口自行删除是一个非常优雅的解决方案,即使它更容易出错。

一个最小的例子:

class Window
{
public:
void keyPressCallback(int c)
{
if (c == KEY_ESC)
{
manager.destroy(this);
return;
}
}
WindowManager& manager;
};

class WindowManager
{
public:
void destroy(Window* target)
{
delete target;
windows.erase(std::find(windows.begin(), windows.end(), target));
}
std::vector<Window*> windows;
};

只要没有剩余的指针指向那个窗口,这个方法就是绝对安全和语义健全的。当窗口收到关闭信号时,它会自行关闭。

带有 dead 标志的相同示例:

class Window
{
public:
Window() : dead(false) {}
void keyPressCallback(int c)
{
if (c == KEY_ESC)
{
dead = true;
return;
}
}
bool dead;
};

class WindowManager
{
public:
void cleanup()
{
for (auto iter = windows.begin(); iter != windows.end(); ++iter)
{
if (iter->dead) windows.erase(iter);
}
}
std::vector<Window*> windows;
};

关于c++ - 实现 "window"系统和 "no deletion of self"规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15595772/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com