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

unique_ptr assignment and copy constructor clarification

我想确保我的代码(确实有效)符合 c++ 规范。正如我想确保所有代码都符合 c++ 标准和规范,尽管它 运行 很好。不完全确定这是否应该在代码审查论坛中进行。如果是这样,请引导我到那里,我会把这个 post 移到论坛上。

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

在注册窗口

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 分配的指针的薄包装器。换句话说 delete m_main_window.get() 将从 Engine 的析构函数中调用 。此外,保留指向通过引用传递的值的指针是一种糟糕的做法,因为无法保证 window 对象的寿命与 Engine::m_main-window.[= 一样长。 17=]

正如@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 必须 分配新的。该引擎将获得指针的所有权。