如何将 std::make_unique<derived>() 转换为 std::unique_ptr<base>
How can I convert std::make_unique<derived>() to std::unique_ptr<base>
我正在尝试构建一个基于(https://www.codetg.com/article/7r1QnR43bm3ZogBJ.html)的自注册工厂方法,它注册逻辑操作。但我不知道如何将 std::make_unique 转换为 std::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 函数,如 Whosebug 上的其他示例所示。但这也不一样。
主要
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;
}
LogicAndOperation.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");
有人可以向我解释一下,我如何从派生的 class (LogicAndOperation) 中生成 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;
}
我正在尝试构建一个基于(https://www.codetg.com/article/7r1QnR43bm3ZogBJ.html)的自注册工厂方法,它注册逻辑操作。但我不知道如何将 std::make_unique 转换为 std::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 函数,如 Whosebug 上的其他示例所示。但这也不一样。
主要
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;
}
LogicAndOperation.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");
有人可以向我解释一下,我如何从派生的 class (LogicAndOperation) 中生成 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;
}