我可能完全没有根据,但我来自 c#,所以我提前道歉。
首先,简单介绍一下我正在尝试做的事情。我的代码中定义了一个工厂基类
template<typename _Ty>
class Factory
{
public:
virtual std::shared_ptr<_Ty> Create() = 0;
};
然后我想做的是拥有一个工厂列表(例如 STL vector 或列表),然后能够通过模板类型搜索它们。到目前为止,我已经发现我需要一个 vector 或某种包含类型的列表,所以我想出了:
class FactoryContainer
{
struct FactoryConcept {
virtual ~FactoryConcept() {}
};
template< typename _Ty > struct FactoryModel : FactoryConcept {
FactoryModel( const _Ty& t ) : factory( t ) {}
virtual ~FactoryModel() {}
private:
_Ty factory;
};
std::shared_ptr<FactoryConcept> factory;
public:
template< typename _Ty > FactoryContainer( const _Ty& _factory ) :
factory( new FactoryModel<_Ty>( _factory ) ) {}
};
我想在容器中包含某种方法来比较类型,类似于
template<typename _Ty> bool isType(){...}
但我不知道如何实现它,或者我是否在使用类型删除后确定类型的正确轨道上。
编辑: 在多次评论这是一个 XY 问题之后,我决定再次强调我正在做的事情(我确实说过)。
我想要一个 Factory 类型的 STL 容器(包括任何和所有实例化的模板类型),并且能够通过模板类型提取一个。对我来说,我认为做到这一点的最佳方法(这可能不是最好的方法)是使用类型封装容器类,并让它能够响应包含的类型实际上是使用提供的模板类型。如果不是,那就放弃。我无法按照建议使用dynamic_cast,因为在我试图弄清楚的时候,我没有指向这两种类型的指针。我现在正在研究 typeid,希望它能解决我的问题,但我仍在等待另一个可能的答案。
编辑2: 在玩了几个答案之后,我没有找到完全符合我要求的答案。简而言之,这是要求:
基类模板:
template<typename FactoryType>
class Factory
{
public:
virtual std::shared_ptr<FactoryType> Create() = 0;
virtual ~Factory(){}
};
厂长类:
class Manager
{
static std::shared_ptr<Manager> singleton;
public:
static std::shared_ptr<Manager> getInstance()
{
if (!singleton) singleton = shared_ptr<Manager>(new Manager);
return singleton;
}
template<typename FactoryType>
Factory<FactoryType>& getFactory()
{
//Pick a factory here by the type and return it by reference
//life cycle is handled by the manager
}
};
管理器将被核心可执行文件和各种 dll 所识别。在编译 Manager 时,工厂的可能类型是未知的,并且由彼此不了解的代码引用。很可能,这里加载了我不知道也不会知道的工厂,因为其中许多工厂是由其他人制作并放入 dll 中的。
最佳答案
好吧,由于您使用的是 C++11,因此您可以存储 std::type_index
对象。
您可以使用 typeid
运算符检索它们:typeid
返回一个 const std::type_info&
,但 type_info
不适合使用,例如。作为 map 的键。因此,您为此目的构造了一个 std::type_index 对象。实际的解决方案取决于您。
类似的东西
std::map<std::type_index, std::shared_ptr<factory>>
例如就可以(将 shared_ptr
替换为适合您设计的正确指针类型)。
请注意,在 C++ 中,您会尽力避免运行时类型信息。如果您暴露了您想要实现的目标,我们可以尝试找到更好的解决方案。
编辑
如果比较 std::type_info
对象的相等性可以跨 DLL 边界工作(因为这是一个要求,请参见您的评论),您可以像这样实现它:
class FactoryContainer
{
struct FactoryConcept {
virtual ~FactoryConcept() {}
virtual const std::type_info& Type() const;
};
template< typename _Ty > struct FactoryModel : FactoryConcept {
FactoryModel( const _Ty& t ) : factory( t ) {}
virtual ~FactoryModel() {}
private:
_Ty factory;
const std::type_info& Type() const { return typeid(_Ty); }
};
std::shared_ptr<FactoryConcept> factory;
public:
template< typename _Ty > FactoryContainer( const _Ty& _factory ) :
factory( new FactoryModel<_Ty>( _factory ) ) {}
template <typename T>
bool hasType() const { return factory->Type() == typeid(T); }
};
用法:
bool result = container.hasType<double>();
关于C++ 类型删除/类型封装?发现型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9486622/