2017-07-22 5 views
-1

Ich möchte sicherstellen, dass der Code, den ich habe (was funktioniert) ist korrekt zu den Spezifikationen zu C++. Wie in ich möchte sicherstellen, dass alles, obwohl es gut läuft, dass der Code C++ - Standards und Spezifikationen erfüllt. Nicht ganz sicher, ob dies eher in einem Code Review Forum sein sollte. Wenn es so ist, bitte leiten Sie mich dorthin und ich werde diesen Beitrag ins Forum verschieben.unique_ptr Zuordnung und Kopie Konstruktor Klärung

engine.h

class Engine final { 
public: 
    void run(); 
    void startup(); 
    Logger& getLogger() const; 

    Engine() = default; 
    ~Engine() = default; 
    Engine(Engine&& engine) = delete; 
    Engine(const Engine& engine) = delete; 
    Engine& operator=(Engine&& engine) = delete; 
    Engine& operator=(const Engine& engine) = delete; 

    void registerWindow(Window&& window); 
    void registerWindow(Window& window); 
private: 
    std::unique_ptr<Logger> m_logger; 
    std::unique_ptr<Window> m_main_window; 
}; 

Engine.cpp

void Engine::registerWindow(Window &&window) { 
    m_main_window = std::move(std::unique_ptr<Window>(&window)); // not confident that this is technically correct. 
} 

void Engine::registerWindow(Window &window) { 
    m_main_window = std::move(std::unique_ptr<Window>(&window)); // not confident that this is technically correct. 
} 

Window.h

class Window { 
public: 
    Window(std::string title, int32_t width, int32_t height); 
    ~Window() = default; 
    Window(const Window& window) = delete; 
    Window(Window&& window) noexcept ; 
    Window& operator=(const Window& window) = delete; 
    Window& operator=(Window&& window) noexcept ; 
    void make_current() const; 
    GLFWwindow* window() const; 
private: 
    std::unique_ptr<GLFWwindow, GLFWdeleter> m_window; 
}; 

Window.cpp

Window::Window(Window &&window) noexcept 
    : m_window(std::move(window.m_window)) 
{ 
} 

Window &Window::operator=(Window &&window) noexcept { 
    if (this == &window) 
     return *this; 
    m_window = std::move(m_window); 
    return *this; 
} 

main.cpp

Window window("Hello World!", 640, 480); 
window.make_current(); 
g_engine.registerWindow(window); 
+0

Sie sollten 'std :: unique_ptr ' für 'Engine :: registerWindow' nehmen. – Jarod42

+0

@ Jarod42 Ich dachte, das wäre besser. Können Sie den Grund näher erläutern? Ich gehe davon aus, dass es damit zu tun hat, dass es ein "unique_ptr" ist. – Matthew

+0

Die Verschiebung in 'std :: move (std :: unique_ptr (p))' ist nicht erforderlich. – Jarod42

Antwort

1

In Registerfenster

std::unique_ptr<Window> m_main_window; // for reference. 

void Engine::registerWindow(Window &&window) 
{ 
    m_main_window = std::move(std::unique_ptr<Window>(&window)); // NOT CORRECT! 
                   // crash waiting to happen! 
} 

std::unique_ptr<> ist eine dünne Hülle für Zeiger mit neuen zugeordnet. Mit anderen Worten: delete m_main_window.get()wird aus dem Destruktor der Engine aufgerufen. Darüber hinaus ist es eine schreckliche Übung, einen Zeiger auf einen Wert zu halten, der als Referenz übergeben wird, da es keine Garantie gibt, dass das window-Objekt so lange wie Engine :: m_main-window bestehen bleibt.

Wie von @ Jarod42, sollten Sie erwägen, einen std :: Empfang unique_ptr als Parameter an RegisterWindow()

void Engine::registerWindow(std::unique_ptr<Window> wnd) 
{ 
    m_main_window = std::move(wnd); 
} 

// call as 
std::unique_ptr<Window> w(new Window); 
engine.registerWindow(std::move(w)); 

Dies stellt sicher, dass der Anrufer versteht, dass wndmuss mit neuen zugeordnet werden. Und diese Engine übernimmt den Besitzer des Mauszeigers.

+0

Vielen Dank, ich habe die Änderungen implementiert. Ich habe jedoch eine Frage, sollten Sie das übergebene 'unique_ptr' nicht auf 'nullptr' setzen, da es nicht länger der Eigentümer ist? – Matthew

+0

'wnd'wurde zurückgesetzt, wenn der Inhalt in' m_main_window' verschoben wurde. unique_ptr geht sehr weit, um sicherzustellen, dass es nur eine Kopie des Zeigers gibt. –

+0

ja meine Entschuldigung – Matthew

Verwandte Themen