【发布时间】:2018-11-30 01:56:01
【问题描述】:
这是我之前帖子的延续。由于它已经关闭,我决定发布一个新帖子。我删除了一半的代码以使其更具可读性。
我读过的一些帖子:
Is it possible to use SDL2 with smart pointers?
Couple of questions about SDL_Window and unique_ptr
class cGraphics
{
public:
// Creator functions
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> Create_Window(int xWin, int yWin);
// ctor & dtor
cGraphics() : m_Window(nullptr, SDL_DestroyWindow) {}
cGraphics(int xWin, int yWin);
~cGraphics();
private:
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> m_Window;
};
cGraphics::cGraphics(int xWin, int yWin)
{
m_Window = std::move(Create_Window(xWin, yWin));
if (m_Window == nullptr)
{
throw "SDL_Window or SDL_Renderer not ready!";
}
}
cGraphics::~cGraphics()
{
IMG_Quit();
SDL_Quit();
}
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> cGraphics::Create_Window(int xWin, int yWin)
{
return std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)>(SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xWin, yWin, SDL_WINDOW_SHOWN), SDL_DestroyWindow);
}
编译器抱怨:
'std::unique_ptr<SDL_Window,void (__cdecl *)(SDL_Window *)>::unique_ptr': no appropriate default constructor available
我了解,当编译器无法找到某些成员的默认构造函数时,通常会出现此错误。然而,这不是真的,因为我明确声明了 std::unique_ptr 的默认值。
如果编译器实际上在抱怨 SDL_Window,这是一个不完整的类型(C 结构),我该怎么办?
【问题讨论】:
-
顺便说一句,考虑手动定义您自己的删除器 (
struct Invoke_SDL_DestroyWindow { void operator()(SDL_WINDOW* p) const noexcept { SDL_DestroyWindow(p); } };) 并使用它,而不是拖着其他指针并通过它们间接。 -
@Deduplicator 所说的非常正确。
std::unique_ptr带有删除函数指针的大小是没有它的指针的两倍。这是浪费空间。你拖着一个你永远不会改变的额外指针,它也使编译器更难优化(它可能无法判断删除函数永远不会改变)。如果太痛苦(IMO 是这样),请编写一个简单的包装器,从函数指针创建一个删除器:godbolt.org/g/sM75NC(C++17,但您可以在它之前接近该语法) -
@Justin: 或者,add an explicit template-specialization:
template <> inline void std::default_delete<SDL_Window>::operator()(SDL_Window* p) const { SDL_DestroyWindow(p); }可能更容易。 coliru.stacked-crooked.com/a/91120d518230a816 -
@Deduplicator 这是允许的边界。我强烈建议不要这样做。这很容易出错。考虑
SDL_Window*是如何由SDL_CreateWindow创建的,而不是通过new SDL_Window;创建的。因此,在编写该代码之后,如果编写了std::make_unique<SDL_Window>(...),您将有未定义的行为。简而言之,这非常容易搞砸。 -
@Justin:由于
SDL_Window不完整,对std::make_unique的调用将导致编译错误。那里没有危险。
标签: c++ sdl unique-ptr