没有适用于std :: unique_ptr的默认构造函数

Nic*_*rey 2 c++ sdl unique-ptr

这是我之前的帖子的延续.由于它已经关闭,我决定发一个新帖子.我删除了一半的代码,使其更具可读性.

我读到的一些帖子:

SDL的智能指针

是否可以将SDL2与智能指针一起使用?

关于SDL_Window和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);
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨说:

'std::unique_ptr<SDL_Window,void (__cdecl *)(SDL_Window *)>::unique_ptr': no appropriate default constructor available
Run Code Online (Sandbox Code Playgroud)

我知道当编译器找不到某些成员的默认构造函数时,通常会出现此错误.然而,这不是真的,因为我明确声明了默认值std::unique_ptr.

如果编译器实际上在抱怨SDL_Window,这是一个不完整的类型(C结构),我该怎么办呢?

Nat*_*ica 6

A std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)>不是默认构造的.这意味着

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!";
    }
}
Run Code Online (Sandbox Code Playgroud)

当你到达零件时***,编译器将尝试默认构造,m_Window因为你没有在成员初始化列表中这样做.来自编译器ro默认构造的尝试m_Window是导致错误的原因.我们可以通过m_Window = std::move(Create_Window(xWin, yWin));移出构造函数体并将其放在成员初始化列表中来解决这个问题

cGraphics::cGraphics(int xWin, int yWin) : m_Window(Create_Window(xWin, yWin))
{   
    if (m_Window == nullptr)
    {
        throw "SDL_Window or SDL_Renderer not ready!";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想这样做,那么您可以委托默认构造函数,然后分配给m_Window您最初所做的事情.那看起来像

cGraphics::cGraphics(int xWin, int yWin) : cGraphics()
{
    m_Window = Create_Window(xWin, yWin);

    if (m_Window == nullptr)
    {
        throw "SDL_Window or SDL_Renderer not ready!";
    }
}
Run Code Online (Sandbox Code Playgroud)