共享指针只能通过std::shared_ptr进行初始化.std::make_shared构造函数不起作用

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

本文关键字:std shared 初始化 make 构造函数 不起作用 ptr 共享 指针      更新时间:2023-10-16

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

_window变量是私有类成员:

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:...includetype_traits(984): error C2027: use of undefined type 'SDL_Window'

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

仅仅通过将std::shared_ptr更改为std::make_shared,是什么可能导致抛出这样的错误?

首先解决您的问题:make_shared仅在资源获得new的情况下有帮助,在这种情况下它不是。您必须使用普通的shared_pointer构造函数和SDL_CreateWindow返回的资源。然而,这并不是全部,您还必须传入一个知道如何调用SDL_DestroyWindow来释放资源的deleter。

make_shared用于创建一个新对象,而不是假定现有对象的所有权。
函数本身构造对象,因此它需要类定义。

("Make shared"不是指"使这个指针被共享",而是"使一个对象可以被共享"。这是"让我做披萨"的"制造",而不是"让我成为摇滚明星"的"制造"——也就是说,创造,而不是转化。

你不能在这里使用make_shared,因为创建SDL_Window的唯一方法是通过SDL_CreateWindow
(既然窗口已经存在,那就没有意义了。)

您还需要向构造函数传递一个自定义删除函数,因为SDL需要一个特定的函数来销毁窗口:

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

std::make_shared<T>实际用于构造类型为T的对象。SDL_Window是一个不完全类型,不能在SDL本身之外构造。这种类型的对象只能通过像SDL_CreateWindow这样的SDL调用来构造。

当你在make_shared内部构造对象时,你应该只使用make_shared。而你不是。所以直接使用shared_ptr<T>