关于 SDL_Window 和 unique_ptr 的几个问题

9

我目前遇到了一个问题,需要将SDL_Window指针存储为std::unique_ptr。
我尝试的方法是:

std::unique_ptr<SDL_Window> window_;

解决方案:
std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> window_;

第一次尝试在内存头文件中不断抛出错误,说SDL_Window是一个不完整的类型。我知道SDL_Window是一个结构体,不能被实例化。
SDL_Window* window_ = new SDL_Window();

因此,使用SDL_CreateWindow(params)进行实例化。 问题如下:
  1. Why can't I call the default constructor (or any other) for SDL_Window?

  2. Why does the unique_ptr needs a deleter in this case, but not here:

    renderSystem_ = std::unique_ptr<Renderer::RenderSystem>(new Renderer::RenderSystem());
    

    RenderSystem being a class with just a default constructor, destructor.
    Is it because the unique_ptr can access the destructor, which acts as the deleter and doesn't need to come as a template argument?


1
有一个原因。当您创建指向SDL_Window的指针时,它应该是nullptr。为什么?因为您很可能会调用分配内存的SDL_CreateWindow函数。 - Poriferous
基本上,不允许自己分配内存,因为SDL_CreateWindow更懂得如何分配。如何实现这一点(例如在我的自定义类中)?我已经阅读了有关delete运算符的文章,但我认为删除默认构造函数并没有多大意义。 - EmeraldOverflow
4
请记住,SDL是用C语言编写的,不幸的是像我们这样的C++用户必须适应SDL的方式。例如,您不会调用delete window_,而是调用SDL_DestroyWindow(window_),以释放内存。任何非SDL的内容都可以使用unique_ptr、new和delete,就像正常情况下一样,但因为SDL是用C语言编写的,所以它没有unique_ptr、new和delete,无法识别您使用的语法。即使您能够调用new SDL_Window,由于该分配的内存将被SDL_CreateWindow()返回的内容覆盖,这仍然没有意义。 - Poriferous
2个回答

9

SDL_Window类型是不完整的,就像编译器所说的那样。

SDL库在C语言中使用一种常见的模式:指向不完整类型的指针。

在创建唯一指针的时候,SDL_Window类型在编译器看来是这样的:

struct SDL_Window;

这是创建不完整类型的一种方法。

编译器只知道SDL_Window是一种类型,而不是全局变量或函数。这也意味着它不能假设它的大小,也不能假设它有任何构造函数或析构函数。

至于指向SDL_Window的唯一指针,另一种方法是使用以下内容:

struct SDLWindowDestroyer
{
    void operator()(SDL_Window* w) const
    {
        SDL_DestroyWindow(w);
    }
};

std::unique_ptr<SDL_Window, SDLWindowDestroyer> window_;

现在您不需要在构造函数中提供一个函数给window_了。

5
我觉得这个更简洁:
    auto window = std::unique_ptr<SDL_Window, std::function<void(SDL_Window *)>>(
            SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, kWindowWidth, kWindowHeight, 0),
            SDL_DestroyWindow
    );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接