我正在使用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>