0

Update I read the other post and figured out that I can write: cGraphics() : m_Window(nullptr, SDL_DestroyWindow), m_Renderer(nullptr, SDL_DestroyRenderer) {}, which removes the first error. However it still shows the second error:

error C2512: 'std::unique_ptr::unique_ptr': no appropriate default constructor available

End of Update

I'm trying to use smart pointers with SDL2 and so far I'm struggling with the grammar:

#pragma once

#include <memory>
#include <unordered_map>
#include <string>
#include "SDL.h"
#include "SDL_image.h"

struct cRGB
{
    int r, g, b;
};

class cGraphics
{
public:
    //  Creator functions for initialization
    bool Create_Window(int xWin, int yWin);
    bool Create_Renderer();
    bool Create_Texture(std::string texid, std::string texres, int r, int g, int b);

    //  ctor & dtor
    cGraphics() : m_Window(std::make_unique<SDL_Window>(nullptr, [](SDL_Window* w) {delete w; })), m_Renderer(std::make_unique<SDL_Renderer>(nullptr, [](SDL_Renderer* r) {delete r; })) {}
    cGraphics(int xWin, int yWin);
    ~cGraphics();

    //  Rendering
    void ClearScreen();
    void RenderTexture(std::string texres, int xDes, int yDes);
private:
    m_Renderer(nullptr, SDL_DestroyRenderer) {}
    std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> m_Window;
    std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> m_Renderer;
    std::unordered_map<std::string, std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>> m_Texture;

    //  Creator helper
    SDL_Texture* CreateTextureRawPtr(std::string texres, int r, int g, int b);
};

cGraphics::cGraphics(int xWin, int yWin)
{
    if (!Create_Window(xWin, yWin) || !Create_Renderer())
    {

    }
}

cGraphics::~cGraphics()
{
    IMG_Quit();
    SDL_Quit();
}

void cGraphics::ClearScreen()
{
    SDL_RenderClear(m_Renderer.get());
}

void cGraphics::RenderTexture(std::string texres, int xDes, int yDes)
{
    SDL_Rect g_SrcRect = { 0, 0, 32, 32 };          //  hard-coded for test
    SDL_Rect g_DesRect = { xDes, yDes, 32, 32 };
    SDL_RenderCopy(m_Renderer.get(), m_Texture[texres].get(), &g_SrcRect, &g_DesRect);
}

bool cGraphics::Create_Window(int xWin, int yWin)
{
    m_Window.reset(SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xWin, yWin, SDL_WINDOW_SHOWN));
    return true;
}

bool cGraphics::Create_Renderer()
{
    m_Renderer.reset(SDL_CreateRenderer(m_Window.get(), -1, 0));
    SDL_SetRenderDrawColor(m_Renderer.get(), 255, 255, 255, 0xff);
    return true;
}

bool cGraphics::Create_Texture(std::string texid, std::string texres, int r, int g, int b)
{
    m_Texture.emplace(texid, std::make_unique<SDL_Texture>(CreateTextureRawPtr(texres, r, g, b)));
    return true;
}

SDL_Texture* cGraphics::CreateTextureRawPtr(std::string texres, int r, int g, int b)
{
    SDL_Surface* temp = IMG_Load(texres.c_str());
    //Set color key
    SDL_SetColorKey(temp, SDL_TRUE,
        SDL_MapRGB(temp->format, r, g, b));

    SDL_Texture* pTexture = SDL_CreateTextureFromSurface(m_Renderer.get(), temp);

    SDL_FreeSurface(temp);
    return pTexture;
}

I got two errors:

First one on this line (I added this line thinking that it may solve second error:

cGraphics() : m_Window(std::make_unique<SDL_Window>(nullptr, [](SDL_Window* w) {delete w; })), m_Renderer(std::make_unique<SDL_Renderer>(nullptr, [](SDL_Renderer* r) {delete r; })) {}

It complains that no instances of the constructor matches the arguments. Basically I'm trying to initialize them with a default deletor and use reset to put a real deletor which is SDL_DestroyWindow().

This error causes a chain reaction and almost every line contains an error. So I'm assuming that once this is fixed most of the other errors will disappear.

The second error (i.e. if I remove the line causing the first error):

cGraphics::cGraphics(int xWin, int yWin)
{
    if (!Create_Window(xWin, yWin) || !Create_Renderer())
    {

    }
}

I didn't complete the inner code block, but it's already complaining that

No default ctor for class std::unique_ptr

I'm not sure how to proceed from here, and even googling shows zero result for this particular error. So I think maybe it's because there is no default ctor (I actually want to put the default ctor to private) , and I added the line which causes the first error.

Nicholas Humphrey
  • 1,043
  • 14
  • 29
  • 2
    `make_unique` is incompatible with custom deleters. – François Andrieux Jun 20 '18 at 17:59
  • @FrançoisAndrieux Thanks I'll try the other methods in that post. BTW is there a way to hide the default ctor and explicitly use the Creator functions? – Nicholas Humphrey Jun 20 '18 at 18:15
  • Hi! I change the code to `cGraphics() : m_Window(nullptr, SDL_DestroyWindow), m_Renderer(nullptr, SDL_DestroyRenderer) {}` and now the first error disappears. The second one still shows and I'm not sure how to deal with it. I thought providing a default ctor is good enough but it seems to be more than this. – Nicholas Humphrey Jun 20 '18 at 18:19

0 Answers0