unique_ptr赋值和复制构造函数说明

时间:2017-07-22 21:20:54

标签: c++ unique-ptr glfw

我想确保我的代码(确实有效)对c ++的规范是正确的。正如在我想确保尽管它运行正常,代码符合c ++标准和规​​范。不完全确定这是否应该在代码审查论坛中。如果是这样,请指导我,我将把这篇文章移到论坛。

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);

1 个答案:

答案 0 :(得分:1)

在RegisterWindow中

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<>是用new分配的指针的瘦包装器。换句话说,将从Engine的析构函数中调用delete m_main_window.get() 。另外,保持指向通过引用传递的值的指针是一种可怕的做法,因为无法保证window对象将与Engine :: m_main-window一样长。

正如@ Jarod42所指出的那样,你应该考虑接收一个std :: unique_ptr作为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));

这可确保调用者了解wnd 必须分配新内容。该引擎将获得指针的所有权。