如何将标准::make_unique<derived>() 转换为标准::unique_ptr<base>

How can I convert std::make_unique<derived>() to std::unique_ptr<base>

本文关键字:unique gt lt 标准 转换 base ptr derived make      更新时间:2023-10-16

我正在尝试构建一个基于(https://www.codetg.com/article/7r1QnR43bm3ZogBJ.html(的自注册工厂方法,该方法注册逻辑操作。但是我不知道如何将标准::make_unique转换为标准::make_unique。我总是收到相同的错误:

return': cannot convert from 'std::unique_ptr<T1,std::default_delete<_Ty>>' to 'std::unique_ptr<LogicOperation,std::default_delete<_Ty>>

我仍然是唯一指针主题的菜鸟,但我已经阅读了 cppreference.com

If T is a derived class of some base B, then std::unique_ptr<T> is implicitly convertible to std::unique_ptr<B>. 
The default deleter of the resulting std::unique_ptr<B> will use operator delete for B, 
leading to undefined behavior unless the destructor of B is virtual.

我尝试使用std::move((而不是制作lambda函数,如堆栈溢出上的其他示例所示。但这也不起作用。

主要

int main()
{
    Signal a;
    Signal b;
    a.setState(1);
    b.setState(0);
    std::unique_ptr<LogicOperation> logic = LogicOperationFactory::Create("AND");
    bool x[2] = { a.getState(), b.getState() };
    bool y = logic->operation(x, 2); // do and operation
}

LogicOperation.h

class LogicOperation
{
public:
    LogicOperation() = default;
    virtual ~LogicOperation() = default;
public:
    virtual bool operation(bool*, uint8_t count) = 0;
};

LogicOperationFactory.h:

        using TCreateMethod = std::function<std::unique_ptr<LogicOperation>()>;
    template<class T1>
    static bool Register(const std::string name)
    {
        std::map<std::string, TCreateMethod>::iterator it;
        it = s_methods.find(name);
        if (it != s_methods.end())
            return false;
        s_methods[name] = []() -> std::unique_ptr<LogicOperation> {
            // Constructs an object of type T and wraps it in a std::unique_ptr
            return std::make_unique<T1>(); // use default constructor
        };
        return true;
    }

逻辑与操作.cpp

class LogicAndOperation :
    public virtual LogicOperation
{
public:
    LogicAndOperation() = default;
    virtual ~LogicAndOperation() = default;
    bool operation(bool* signals, uint8_t count) override;
private:
    static bool s_registered;
};
bool LogicAndOperation::s_registered =
LogicOperationFactory::Register<LogicAndOperation>("AND");

有人可以向我解释一下,我如何从派生类(逻辑和操作(制作 std::unique_ptr?

给定示例代码,我看不到问题。

这在C++14模式(Clang 10(下编译并运行。我填补了我们的示例代码所缺乏的一些空白。我看不到你的LogicOperationFactory::Create()功能;这就是你的问题所在吗?

#include <cassert>
#include <cstdint>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
class LogicOperation
{
public:
    virtual ~LogicOperation() = default;
    virtual bool operation(bool*, uint8_t count) = 0;
};
using TCreateMethod = std::function<std::unique_ptr<LogicOperation>()>;
class LogicOperationFactory
{
    static std::map<std::string, TCreateMethod> s_methods;
public:
    template<class T>
    static bool Register(const std::string& name)
    {
        std::map<std::string, TCreateMethod>::iterator it;
        it = s_methods.find(name);
        if (it != s_methods.end())
            return false;
        s_methods[name] = []() -> std::unique_ptr<LogicOperation> {
            // Constructs an object of type T and wraps it in a std::unique_ptr
            return std::make_unique<T>(); // use default constructor
        };
        return true;
    }
    static std::unique_ptr<LogicOperation> Create(const std::string& name)
    {
        auto iter = s_methods.find(name);
        return (iter != s_methods.end()) ? (iter->second)() : nullptr;
    }
};
std::map<std::string, TCreateMethod> LogicOperationFactory::s_methods;
class FooLogic : public LogicOperation
{
public:
    bool operation(bool*, uint8_t) override {
        std::cout << "FooLogic::operation" << std::endl;
        return true;
    }
};
class BarLogic : public LogicOperation
{
public:
    bool operation(bool*, uint8_t) override {
        std::cout << "BarLogic::operation" << std::endl;
        return true;
    }
};
static bool s_registeredFooLogic = LogicOperationFactory::Register<FooLogic>("FooLogic");
static bool s_registeredBarLogic = LogicOperationFactory::Register<BarLogic>("BarLogic");
int main() {
    assert(s_registeredFooLogic && s_registeredBarLogic);
    auto bar_logic = LogicOperationFactory::Create("BarLogic");
    bool flag = false;
    bar_logic->operation(&flag, 1);
    auto null_logic = LogicOperationFactory::Create("ThisDoesNotExist");
    assert(nullptr == null_logic);
    return 0;
}