2013-08-19 40 views
6

SDL_Window構造体へのポインタを作成し、それをshared_ptrに割り当てると、前述のエラーが発生します。クラスの不完全な型 'SDL_Window'への 'sizeof'の無効なアプリケーション

パート:

#include <SDL2/SDL.h> 

class Application { 
    static std::shared_ptr<SDL_Window> window; 
} 

定義:

#include "Application.h" 
std::shared_ptr<SDL_Window> Application::window{}; 

bool Application::init() { 
    SDL_Window *window_ = nullptr; 
    if((window_ = SDL_CreateWindow(title.c_str(), 
            SDL_WINDOWPOS_UNDEFINED, 
            SDL_WINDOWPOS_UNDEFINED, 
            window_width, 
            window_height, 
            NULL) 
     ) == nullptr) { 
     std::cerr << "creating window failed: " << SDL_GetError() << std::endl; 
    } 

    window.reset(window_); 
} 

エラーが 'window.reset()' で表示されます。理由は何ですか?この動作を修正する方法は何ですか?

+1

は多分無関係な、しかし、あなたはSDL_DestroyWindow経由で割り当て解除の代わりに、削除する必要はありません。

struct SDLWindowDeleter { inline void operator()(SDL_Window* window) { SDL_DestroyWindow(window); } }; 

は、次にテンプレートパラメータを経由してデリータが含まれていますか? – PlasmaHH

答えて

8

デフォルトでは、shared_ptrdeleteを使用して管理対象リソースを解放します。しかし、あなたは別の方法を解放する必要があるリソースを使用している場合、カスタム削除手段が必要になります:

window.reset(window_, SDL_DestroyWindow); 

は注:私はこれが動作しますかなり確信しているが、私はSDLを持っていませんそれを使ってテストするためのインストール。

+0

@vmrob:申し訳ありません、それはタイプミスでした。私は関数 'SDL_DestroyWindow'を意味していました。関数ポインタは、クラス内でラップすることなく、十分でなければなりません。 –

7

前述したように、Mikeとすると、shared_ptrと指定する必要があります。しかし、unique_ptrの場合、テンプレートパラメータとしてきちんと使えるように、あなたのデリターに特別な型を作成したいと思うでしょう。私は、この構造体を使用:

std::unique_ptr<SDL_Window, SDLWindowDeleter> sdlWindowPtr = SDL_CreateWindow(...); 
+0

そのようなクラスに関数呼び出しをラップする必要はありません。 deleterは、 'SDL_DestroyWindow'へのポインタを含む、適切に呼び出すことのできるオブジェクトであればどれでもかまいません。 –

+0

'std :: unique_ptr'と一緒に使うと、関数ポインタとは違った型が必要でしょうか? – vmrob

+2

申し訳ありませんが、私はあなたが 'unique_ptr'に言い聞かせされたことに気付かなかった。これは、関数ポインタを含む適切に呼び出せるオブジェクトを取ることもできます。これは、テンプレートをインスタンス化するときにDeleter型を明示的に指定する必要があるので(つまり、 'std :: unique_ptr ')、カスタムクラスの型がニータ。 –

関連する問題