【问题标题】:How to correctly manage initialisation in constructor?如何正确管理构造函数中的初始化?
【发布时间】:2021-05-04 16:04:17
【问题描述】:

我正在用 C++ 围绕 GLFW 和 OpenGL 编写一个简单的包装器,作为练习。我有一个班级Window 和一个班级RendererWindow 类拥有一个 Renderer 成员。

Window 在其构造函数中设置 GLFW 上下文并运行主循环,并调用其 Renderer 成员进行绘制。 Renderer 在其构造函数中设置缓冲区,并执行 OpenGL 操作。

我遇到的问题是 OpenGL 调用 require 以获得可用的 OpenGL 上下文。如果我只是在调用Window 的构造函数之前初始化Renderer,那么将在创建GLFW 上下文之前调用Renderer 的构造函数。

我所做的是将unique_ptr 存储到Window 中的Renderer,然后在Window 的构造函数中调用std::make_unique<Renderer>。然后,在析构函数中,我在销毁 GLFW 上下文之前调用 std::unique_ptr::reset(),这样我就可以调用 OpenGL 来释放具有仍然有效上下文的东西。

class Window
{
   public:
       Window()
       {
           //initialising GLFW and creating an OpenGL context
           //...
           m_renderer = std::make_unique<Renderer>();
       }
       ~Window()
       {
           m_renderer.reset();
           glfwTerminate();
       }
       int run()
       {
           while(...)
           {
               m_renderer->draw();
               //...
           }
           return 0;
       }
   private:
       std::unique_ptr<Renderer> m_renderer; 
       //...
}

class Renderer
{
    public:
        Renderer() { //Set buffers }
        ~Renderer() { //Free buffers }
        draw() { glDrawElements(...); //... }
    private:
        //...
}

int main()
{
     Window window();
     return window->run();
}
        

我知道对象应该已经在构造函数的主体中初始化,但这里不是这种情况。我觉得我可能在 RendererWindow 之间做了一些依赖,或者我的一般架构是错误的。我宁愿依赖于根据作用域在正确的时刻调用构造函数和析构函数,而不是我手动触发它。

什么是更好的解决方案?

【问题讨论】:

    标签: c++ opengl glfw abstraction glew


    【解决方案1】:

    我建议您创建一个单独的类,将其命名为 GLFWInit,它会执行 GLFW 初始化并在其析构函数中调用 glfwTerminate()。那么你有两个选择:

    1. Window 类中嵌入GLFWInit 类型的对象。尽早放置成员,但至少在 m_renderer 成员之前。

    2. GLFWInit 派生您的Window 类。

    这两种方法都确保 GLFW 在 m_renderer 之前初始化并在它之后拆除。然后,您甚至不必将渲染器设为指针,并且可以直接嵌入成员(如果可行的话)。

    【讨论】:

    • 接缝确实可行。这是常见的做法吗?
    • 它遵循 RAII 习语。在这方面,这是常见的做法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    相关资源
    最近更新 更多