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

时间:2016-08-12 14:19:47

标签: c++ c++11 pointers sdl smart-pointers

我正在使用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:\...\include\type_traits(984): error C2027: use of undefined type 'SDL_Window'

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

只需将std::shared_ptr更改为std::make_shared,可能导致抛出此类错误的原因是什么?

3 个答案:

答案 0 :(得分:7)

首先解决您的问题:make_shared仅在使用new获取资源的情况下才有用,在这种情况下不是shared_pointer。您必须使用SDL_CreateWindow返回的资源的普通SDL_DestroyWindow构造函数。但是,这不是完整的故事,您还必须传入一个知道如何调用INSERT INTO table2 (a, column2, c) VALUS(1, (INSERT INTO table1 ... RETURNING id), 33); 来释放资源的删除器。

答案 1 :(得分:4)

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

(&#34;分享&#34;不意味着&#34;让这个指针共享&#34;,但是&#34;制作一个可以共享的对象&#34;它&#39;它&#39; &#34; make&#34;&#34;让我成为一个披萨&#34;而不是&#34;让我成为摇滚明星&#34; - 即创造,而不是变革。)

您无法在此使用make_shared,因为创建SDL_Window的唯一方法是SDL_CreateWindow
(并且因为窗口已经存在,所以没有意义。)

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

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

答案 2 :(得分:2)

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

make_shared内构建对象时,只应使用make_shared。而你却不是。所以直接使用shared_ptr<T>