如何从继承的父类创建unique_ptr

时间:2017-07-24 21:58:21

标签: c++ inheritance unique-ptr

有没有办法从其中一个继承的类创建unique_ptr

我需要能够注册" MouseListeners与经理有关,但我无法弄清楚如何创建继承unique_ptr的{​​{1}}。

错误是无法找到从MouseListenerWindow *的转化。我尝试过MouseListener,但会产生其他错误。我也尝试将static_cast传递给raw pointer,但是当你关闭程序时它确实有效,因为我认为它没有创建导致addMouseListener失败的适当内存。

同样使用delete转移所有权,导致侦听器不触发事件。

std::move()

错误输出

// Window.h
class Window : public MouseManager, public MouseListener {
public:
    Window::Window(std::string title, int32_t width, int32_t height) {
        ...
        this->addMouseListener(std::make_unique<MouseListener>(this)); // ERROR
    }
};

// MouseManager.h
void MouseManager::addMouseListener(std::unique_ptr<MouseListener> listener) {
    m_listeners.emplace_back(listener);
}

// MouseListener.h

MouseListener() = default;

virtual ~MouseListener() = default;
MouseListener(const MouseListener& listener) = default;
MouseListener(MouseListener&& listener) noexcept ;
MouseListener& operator=(const MouseListener& listener) = delete;
MouseListener& operator=(MouseListener&& listener) = delete;

更新

取消引用In file included from /Users/Programmer/CLionProjects/StormEngine/Engine/Window/Window.cpp:5: In file included from /Users/Programmer/CLionProjects/StormEngine/Engine/Window/Window.h:8: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:3141:32: error: no matching constructor for initialization of 'MouseListener' return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/Programmer/CLionProjects/StormEngine/Engine/Window/Window.cpp:17:33: note: in instantiation of function template specialization 'std::__1::make_unique<MouseListener, Window *>' requested here this->addMouseListener(std::make_unique<MouseListener>(this)); ^ /Users/Programmer/CLionProjects/StormEngine/Engine/Window/../Events/Listeners/MouseListener.h:19:5: note: candidate constructor not viable: no known conversion from 'Window *' to 'const MouseListener' for 1st argument; dereference the argument with * MouseListener(const MouseListener& listener) = default; ^ /Users/Programmer/CLionProjects/StormEngine/Engine/Window/../Events/Listeners/MouseListener.h:20:5: note: candidate constructor not viable: no known conversion from 'Window *' to 'MouseListener' for 1st argument; dereference the argument with * MouseListener(MouseListener&& listener) noexcept ; ^ /Users/Programmer/CLionProjects/StormEngine/Engine/Window/../Events/Listeners/MouseListener.h:16:5: note: candidate constructor not viable: requires 0 arguments, but 1 was provided MouseListener() = default; ^ 添加了一个新问题,即在this添加变量listener,导致所有权变更,如上所述导致事件无法触发。

2 个答案:

答案 0 :(得分:1)

make unique创建该类型的对象并返回指向它的指针。

它不会将对象的预先存在的指针包装到唯一的ptr中。

您的addMouseListener(std::unique_ptr<MouseListener>)函数取得了收听者的所有权。传递预先存在的对象通常不是一个好主意。

可能Window不应继承MouseListener,而是创建一个MouseListener,而Window又指向Window,并以某种方式进行生命周期管理以确保Window 1}}活着留在身边,或者当MouseListener死亡时我们断开连接。

{{1}}应该中继消息到窗口,而不是 窗口。

答案 1 :(得分:0)

std::make_unique<MouseListener>(this)

这将分配一个新的MouseListener实例,其中this作为构造函数的参数。正如错误消息所解释的那样,没有构造函数MouseListener:MouseListener(Window*)或任何其他具有可以隐式转换Window*的参数的构造函数。

您可能不打算创建新的MouseListener实例,而是想要一个指向this的唯一指针。您可以使用构造函数unique_ptr创建thisexplicit unique_ptr(pointer p)

std::unique_ptr<Window>(this)

此指针可以传递给MouseManager::addMouseListener。请注意,虽然从派生唯一指针的转换是隐式的,但是基本唯一指针不能直接从裸派生指针构造,因为构造函数是显式的。

请注意,创建指向this的唯一指针可能是一个可疑的想法。它将Window对象的创建限制为使用new,并且显然(从分配的代码的角度来看)泄漏指针。没有其他代码可以拥有任何窗口(除非从最初存储它的容器移动),并且您永远不能拥有自动实例。