gpt4 book ai didi

c++ - 使用 C++ 和 glfw 的 raii 架构

转载 作者:行者123 更新时间:2023-11-30 05:05:18 24 4
gpt4 key购买 nike

我目前正在尝试使用 glfw 用 C++ 编写一个小型引擎用于创建窗口。我想充分利用 raii 来提出一个异常安全的架构,并使引擎几乎不可能以错误的方式使用。但我目前正在为一些问题而苦苦挣扎,我觉得我错过了一些重要的东西,所以我在这里问,提前谢谢大家!

假设我有一个基本的 raii -结构称为glfw_context那叫glfwInit()ctorglfwTerminate()dtor .它还接受 error-callback并在调用 glfwInit() 之前设置它但我会省略这些细节,因为我想专注于基本问题。我还创建了一个类 glfw_window这需要 const glfw_context&ctor鉴于重载 ctor采用相同类型的参数,但带有 glfw_context&&deleted .

这背后的想法是,当上下文是 rvalue 时它只会在 ctor 期间存在打电话但glfwTerminate()将在所有窗口被正确销毁之前调用(这发生在 dtor 类的 glfw_window 中)。我实现了moves正确为 glfw_windowglfw_context既不能复制也不能移动。但问题从这里开始:我无法阻止用户创建多个 glfw_context实例。所以我选择了staticglfw起成为成员(member)不会暴露类似 glfwIsInit() 的内容这在我的框架范围内解决了这个问题(只有最旧的实例会调用 glfwTerminate() )但是仍然不能保护用户避免编写这样的代码:

std::vector< glfw_window > windows;
{
// introduce explicit scope to demonstrate the problem
glfw_context context{};
windows.emplace_back( context, ... );
}

在这种情况下,上下文仍然不会超过窗口。

有什么好的方法可以解决这个问题吗?我不想将其作为一项要求放入文档中(诸如“上下文必须比每个窗口都长寿”之类的东西似乎对我来说并不适用)。

我目前的方法是使用 std::shared_pointer< glfw_context >作为 glfw_window 的参数的 ctor并将其存储为成员。但是这仍然不能解决我的问题,因为我仍然可以 make_shared< glfw_context >()不同的上下文并将它们传递给不同的窗口。因为只有第一个分配的实例会调用 glfwTerminate()我仍然可以引发上下文在所有窗口之前被破坏的情况。

那么解决此类问题的正确方法是什么?我可以构建一个无论用户如何尝试(错误)使用它都能在这里正常工作的漂亮架构吗?我的其他一些想法包括 private ctorglfw_context和一个 static工厂方法结合 shared_pointer - 方法,但这感觉很像 singleton我怀疑这是处理问题的最佳方式。

最佳答案

您可能会使用单例的变体:

class glfw_context;
std::shared_ptr<glfw_context> CreateContext(); // Make it visible at global scope

class glfw_context
{
glfw_context() {/*Your impl*/}

glfw_context(const glfw_context&) = delete;
glfw_context& operator=(const glfw_context&) = delete;
public:
friend std::shared_ptr<glfw_context> CreateContext()
{
static std::weak_ptr<glfw_context> instance;

auto res = instance.lock();
if (res == nullptr) {
res = std::make_shared<glfw_context>();
instance = res;
}
return res;
}

/* Your impl */
};

然后只要至少有一个对您的实例的“引用”,CreateContext() 就会返回它,否则它会创建一个新的。
不可能有 2 个不同的 glfw_context

实例

关于c++ - 使用 C++ 和 glfw 的 raii 架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48459639/

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