The main difference is that, unlike Java, C ++ does not have a built-in function like forName(String) that performs this task for you. In C ++ you have to implement it.
Now itβs important how you do it. The proposed switch/case method is one way that is straightforward but long. You can automate things:
(1) First, enter an intermediate template class that creates the object, so you do not need to implement a method for each class.
template<class Derived> class ShapeCreator : public Shape { // This class automates the creations public: static Shape* Create () { new Derived(); // Assuming that no-argument default constructor is avaialable } }; class Circle : public ShapeCreator<Circle> { }; class Square : public ShapeCreator<Square> { }; //... and so on
(2) Now inside the class Shape enter one static std::map , which contains a handle for each derived class.
class Shape { public: typedef std::map<std::sting, Shape* (*)()> ShapeMap; static ShapeMap s_ShapeMap; static Shape* Create (const std::string name) { ShapeMap::iterator it = s_ShapeMap.find(name); if(it == s_ShapeMap.end()) return 0; it->second(); } };
(3) The s_ShapeMap filling should be done statically, you can do this before main() is called (be careful with this) or as the first function inside main() . Use a preprocessing trick to automate things:
#define INIT(SHAPE) Shape::s_ShapeMap[#SHAPE] = &SHAPE::Create Shape* InitializeShapeMap () { INIT(Circle); INIT(Square); INIT(Triangle);
Whenever a new form is introduced, just add it as INIT inside the function.
source share