问题描述
标题差不多:可以基于 type_info
创建对象吗?这样做的目的是推迟对象的创建。例如,下面是原始的未延迟代码:
Pretty much the title: Can objects be created based on type_info
? The purpose of this would be to defer the creation of objects. For instance, here's the original "undeferred" code:
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?
如果这不可能,还有其他方法可以推迟对象的构造吗? / p>
If this is not possible, is there any other way to "defer" the construction of objects?
推荐答案
在c ++中,没有等效于基于运行时已知类型创建对象的方法。诸如C#和Java之类的语言之所以能够做到这一点,恰恰是因为它们具有广泛的反射支持,而这在c ++中是最为缺乏的。
In c++ there is no equivalent of creating objects based on runtime-known types. Languages such as C# and Java can do this precisely because of their extensive reflection support, which is mostly lacking in c++.
所有这一切的一个有趣的副作用是c ++开发人员永远无法滑入反映一切的诱人领域。由于基于反射的开发非常方便,因此使用C#和Java构建的企业应用程序中的许多核心功能都围绕反射。我特别想到的是OR / M软件和库,例如AutoMapper for C#,它们大量使用了反射,以至于使用它们的应用程序的整体性能受到严重影响(从个人经验来看)。
One interesting side effect of all this is that c++ developers are never able to slide into the tempting area of reflecting everything. Because of the sheer convenience of reflection-based development lots of core functionality in enterprise applications built with C# and Java revolves around reflection. I'm thinking in particular of OR/M software and libraries such as AutoMapper for C# which make such extensive use of reflection that the overall performance of applications that use them suffers significantly (speaking from personal experience). It is actually refreshing to me to be prevented from that in c++.
好消息是,使用控制体系结构的双重反转很有可能实现插件体系结构。以下是一个非常简单的示例,显示了一个单独的dll可以如何使用基本多态性动态注册类型。
The good news is that plugin architectures are very possible using a double inversion of control architecture. Following is a very simple example showing how a separate dll or so could dynamically register types using basic polymorphism.
#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...
这篇关于可以基于type_info创建对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!