In C ++, there is no equivalent to creating objects based on types known at run time. Languages ββsuch as C # and Java can do this precisely because of their extensive support for reflection, which is mostly lacking in C ++.
One interesting side effect of all this is that C ++ developers can never slip into a seductive area that reflects everything. Because of the simplicity of reflection-based development, many key features in enterprise applications built in C # and Java revolve around reflection. I mean, in particular, OR / M software and libraries such as AutoMapper for C # that use reflection so widely that the overall performance of the applications that use them suffers significantly (speaking of personal experience). It really refreshes me so that it can be prevented with C ++.
The good news is that plugin architectures are very affordable using the double inverse of the management architecture. The following is a very simple example showing how a single dll or so can 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; }
Expected Result:
Starting Limousine... Turning on limo accessories... Starting Tractor... Turning on hydraulics...
source share