开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜