2013-08-19 9 views
6

Erstellen eines Zeigers auf eine SDL_Window-Struktur und Zuweisen zu einem shared_ptr, der genannte Fehler resultiert.Ungültige Anwendung von 'sizeof' auf unvollständigen Typ 'SDL_Window'

Ein Teil der Klasse:

#include <SDL2/SDL.h> 

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

Definition:

#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_); 
} 

Der Fehler erscheint bei 'window.reset()'. Was ist der Grund und wie kann dieses Verhalten behoben werden?

+1

Vielleicht nicht verwandten, aber haben Sie nicht über SDL_DestroyWindow statt löschen freizugeben? – PlasmaHH

Antwort

8

Standardmäßig gibt shared_ptr die verwaltete Ressource unter Verwendung von delete frei. Wenn Sie jedoch eine Ressource verwenden, die ein andere Art und Weise muss die Freigabe, werden Sie einen benutzerdefinierten deleter benötigen:

window.reset(window_, SDL_DestroyWindow); 

HINWEIS: Ich bin ziemlich sicher, dass dies funktionieren wird, aber ich habe nicht eine SDL Installation, um es zu testen.

+0

@vmrob: Sorry, das war ein Tippfehler, ich meinte die Funktion 'SDL_DestroyWindow'. Der Funktionszeiger sollte ausreichend sein, ohne ihn in eine Klasse zu integrieren. –

7

Wie zuvor unter Mike beschrieben, müssen Sie Ihren Deleter mit shared_ptr angeben. Für einen unique_ptr möchten Sie jedoch wahrscheinlich einen speziellen Typ für Ihren Deleter erstellen, damit dieser sauber als Vorlageparameter verwendet werden kann. Ich habe diese Struktur:

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

Dann schließen die deleter über Template-Parameter:

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

Es ist nicht notwendig, den Funktionsaufruf in einer solchen Klasse zu verpacken. Der Deleter kann ein beliebiges, angemessen aufrufbares Objekt sein, einschließlich eines Zeigers auf 'SDL_DestroyWindow'. –

+0

Wenn Sie es mit einem 'std :: unique_ptr' verwenden, benötigen Sie einen Typ im Gegensatz zu einem Funktionszeiger, richtig? – vmrob

+2

Entschuldigung, ich habe nicht bemerkt, dass du auf "unique_ptr" abgewichen bist. Das kann auch irgendein geeignet aufrufbares Objekt einschließlich eines Funktionszeigers sein. Es wäre etwas unordentlicher, da Sie den Deletertyp beim Instanziieren der Vorlage explizit angeben müssten (dh 'std :: unique_ptr '), so dass ein benutzerdefinierter Klassentyp vorliegen könnte sauberer. –

Verwandte Themen