几乎标题:可以根据type_info
创建对象吗?这样做的目的是推迟创建对象。例如,这里是原始"未延期"代码:
Foo* a = new Foo();
Bar* b = new Bar();
这是推迟的:
// Store type indices into a vector
std::vector<std::type_index> types;
types.push_back(std::type_index(typeid(Foo)));
types.push_back(std::type_index(typeid(Bar)));
// Iterate through vector, create objects? Is it possible?
如果这是不可能的,还有其他方式来推迟&#34;物体的构造?
答案 0 :(得分:7)
在c ++中,没有基于运行时已知类型创建对象的等价物。像C#和Java这样的语言可以准确地实现这一点,因为它们具有广泛的反射支持,而c ++中缺少这种支持。
所有这一切的一个有趣的副作用是c ++开发人员永远无法进入反映一切的诱人领域。由于基于反射的开发非常方便,使用C#和Java构建的企业应用程序中的许多核心功能都围绕着反射。我特别想到的是OR / M软件和库,例如AutoMapper for C#,它们大量使用反射,使用它们的应用程序的整体性能受到严重影响(从个人经验来讲)。在c ++中被禁止使用它实际上令人耳目一新。
好消息是,使用控制架构的双重反转,插件架构非常可行。下面是一个非常简单的例子,展示了一个单独的dll如何使用基本多态来动态注册类型。
#include <string>
#include <list>
#include <unordered_map>
#include <iostream>
// ------------------------------------------------------------
// Host application
class Vehicle
{
public:
virtual ~Vehicle() {} // Allow proper inheritance
virtual void Start() = 0; // Start the vehicle
};
class VehicleFactory
{
public:
virtual ~VehicleFactory() {} // Allow proper inheritance
virtual Vehicle* Create() = 0;
};
class VehicleTypeFactory
{
public:
void RegisterFactory(std::string vehicleType, VehicleFactory* vehicleFactory)
{
_factories.insert(std::pair<std::string, VehicleFactory*>(vehicleType, vehicleFactory));
}
Vehicle* Create(std::string vehicleType)
{
return _factories.at(vehicleType)->Create();
}
std::list<std::string> GetTypes()
{
std::list<std::string> result;
for(auto& item: _factories)
{
result.push_back(item.first);
}
return result;
}
private:
std::unordered_map<std::string, VehicleFactory*> _factories;
};
class Tractor: public Vehicle
{
public:
virtual void Start()
{
std::cout << "Starting Tractor..." << std::endl;
std::cout << "Turning on hydraulics..." << std::endl;
}
};
class TractorFactory: public VehicleFactory
{
public:
virtual Vehicle* Create()
{
return new Tractor();
}
};
// ------------------------------------------------------------
// Plugin library (.dll, .so)
// plugin introduces brand new type of vehicle
class Limousine: public Vehicle
{
public:
virtual void Start()
{
std::cout << "Starting Limousine..." << std::endl;
std::cout << "Turning on limo accessories..." << std::endl;
}
};
class LimousineFactory: public VehicleFactory
{
public:
virtual Vehicle* Create()
{
return new Limousine();
}
};
// ------------------------------------------------------------
// Host startup: register tractor factory
int main()
{
VehicleTypeFactory vehicleTypeFactory;
TractorFactory tractorFactory;
vehicleTypeFactory.RegisterFactory("tractor", &tractorFactory);
// ... load plugin(s) which will register other types of factories
// (
LimousineFactory limousineFactory;
vehicleTypeFactory.RegisterFactory("limousine", &limousineFactory);
// )
// Now create one of each type of vehicle
// and tell it to start itself
for(auto& vehicleType: vehicleTypeFactory.GetTypes())
{
auto vehicle = vehicleTypeFactory.Create(vehicleType);
vehicle->Start();
}
return 0;
}
预期产出:
Starting Limousine...
Turning on limo accessories...
Starting Tractor...
Turning on hydraulics...