共享指针仅通过 std::shared_ptr 初始化。 std::make_shared 构造函数不工作

Shared pointer only initialising via std::shared_ptr. The std::make_shared constructor is not working

我正在使用 SDL2 和 C++ 制作一个基本游戏。我一直在慢慢地将我对原始指针的不良使用改成更安全的智能指针。

_window 变量是私有 class 成员:

private:
    std::shared_ptr<SDL_Window> _window;

以下代码有效:

_window = std::shared_ptr<SDL_Window>(SDL_CreateWindow(
        "Game",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
));

以下代码不起作用:

_window = std::make_shared<SDL_Window>(SDL_CreateWindow(
        "Game",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
));

抛出以下错误:

C:\...\include\type_traits(984): error C2027: use of undefined type 'SDL_Window'

这很令人困惑,因为type_traits 是标准库的一部分。因此,我不确定错误的来源在哪里,但将我的整个项目包含在这里是不可行的。

什么可能导致抛出这样的错误,只需将 std::shared_ptr 更改为 std::make_shared

std::make_shared<T> 旨在实际 构造 类型 T 的对象。 SDL_Window 是一个不完整的类型,不能在 SDL 本身之外构造。该类型的对象只能通过 SDL 调用构造,例如 SDL_CreateWindow.

只有在 make_shared 本身内部构造对象时才应使用 make_shared。而你不是。所以直接用shared_ptr<T>就可以了。

make_shared 用于创建新对象,而不是用于取得现有对象的所有权。
该函数构造对象本身,因此它需要 class 定义。

("Make shared" 并不意味着 "make this pointer shared",而是 "make an object that can be shared"。它是 "make me a pizza" 的 "make",而不是 "make me a rockstar" -也就是说,创造,而不是改造。)

您不能在此处使用 make_shared,因为创建 SDL_Window 的唯一方法是通过 SDL_CreateWindow
(而且没有意义,因为 window 已经存在。)

您还需要将自定义删除函数传递给构造函数,因为 SDL 需要特定函数来销毁 window:

_window = std::shared_ptr<SDL_Window>(SDL_CreateWindow("Game", ...), SDL_DestroyWindow);

首先要解决您的问题:make_shared 仅在使用 new 获取资源的情况下有帮助,而在这种情况下则不然。您必须将正常的 shared_pointer 构造函数与 SDL_CreateWindow 返回的资源一起使用。然而,这还不是全部,您还必须传入一个知道如何调用 SDL_DestroyWindow 来释放资源的删除器。