Storing member function pointers of derived classes in map
I am tryin开发者_如何学JAVAg to implement a factory for two classes Circle, Square both of which inherits from Shape.
class Shape {
public:
virtual static
Shape * getInstance() = 0;
};
class Circle : public Shape {
public:
static const std::string type;
Shape * getInstance() {
return new Circle;
}
};
const std::string Circle::type = "Circle";
class Square : public Shape {
public:
static const std::string type;
Shape * getInstance() {
return new Square;
}
};
const std::string Square::type = "Square";
I want to now create a map with key as shape type (string) and value as a function pointer to getInstance() of the corresponding derived class. Is it possible?
Thanks, Kiran
Okay I got the mistake.
1) shouldn't declare - virtual static Shape * getInstance() = 0; - in Shape class.
2) getInstance() should be static in all other classes.
Here is the complete implementation
class Shape {
public:
virtual
std::string getType() = 0;
};
class Circle : public Shape {
public:
static const std::string type;
Circle() {
}
std::string getType() {
return type;
}
static
Shape * getInstance() {
return new Circle;
}
};
const std::string Circle::type = "Circle";
class Square : public Shape {
public:
static const std::string type;
Square() {
}
std::string getType() {
return type;
}
static
Shape * getInstance() {
return new Square;
}
};
const std::string Square::type = "Square";
class Triangle : public Shape {
public:
static const std::string type;
Triangle() {
}
std::string getType() {
return type;
}
static
Shape * getInstance() {
return new Triangle;
}
};
const std::string Triangle::type = "Triangle";
typedef Shape * (*getShape)();
typedef std::map<std::string, getShape > factoryMap;
class ShapeFactory {
public:
static factoryMap shapes;
Shape * getInstance(const std::string & type){
factoryMap::iterator itr = shapes.find(type);
if (itr != shapes.end()){
return (*itr->second)();
}
return NULL;
}
};
factoryMap ShapeFactory::shapes;
class ShapeFactoryInitializer {
static ShapeFactoryInitializer si;
public:
ShapeFactoryInitializer() {
ShapeFactory::shapes[Circle::type] = &Circle::getInstance;
ShapeFactory::shapes[Square::type] = &Square::getInstance;
ShapeFactory::shapes[Triangle::type] = &Triangle::getInstance;
}
};
ShapeFactoryInitializer ShapeFactoryInitializer::si;
Although not much relevant to your question, but if you are interested in modern C++ design (factories, smart pointers, etc.), you may like to check this book:
http://www.amazon.co.uk/Modern-Design-Applied-Generic-Patterns/dp/0201704315/ref=sr_1_20?s=books&ie=UTF8&qid=1293359949&sr=1-20
It talk about factories, how to design them, etc.
PS: I am not the author of the book, nor I have been given any thing in return for posting this answer :-)
Change the last line of your code to ShapeFactoryInitializer ShapeFactoryInitializer::si;
, then it will pass compilation.
精彩评论