工厂模式 - 在静态成员函数中无效使用成员

时间:2013-03-30 20:19:25

标签: c++ factory-pattern

我是C ++中这个工厂模式的新手,我在尝试实现其中一个方法时得到了标题我收到了以下错误:

静态成员函数中成员'creationFunctions'的使用无效

typedef Shape (*createShapeFunction)(void);
/* thrown when a shape cannot be read from a stream */
class WrongFormatException { };

class ShapeFactory {

public:

    static void registerFunction(const std::string &string, const createShapeFunction *shapeFunction);
    static Shape *createShape(const std::string &string);
    static Shape *createShape(std::istream &ins);

private:

    std::map<std::string, createShapeFunction *> creationFunctions;
    ShapeFactory();
    static ShapeFactory *getShapeFactory();
};


void ShapeFactory::registerFunction(const std::string &string, const createShapeFunction *shapeFunction)
{
    creationFunctions.at(string) = shapeFunction;
}

2 个答案:

答案 0 :(得分:1)

您无法从静态成员函数访问类的非静态成员。在你的例子中,可能最好的想法是使所有成员函数都是非静态的,除了“getShapeFactory”,然后它将充当Mayer的单例生成器......

答案 1 :(得分:1)

我看到的一个问题是您正在从静态函数访问ShapeFactory的私有变量。静态函数不依赖于ShapeFactory的特定实例,因此您无法访问非静态私有变量。另一个副作用是this未在静态函数的上下文中定义。每次创建ShapeFactory的实例时,都会为每个std::map<std::string, createShapeFunction *> creationFunctions创建一个ShapeFactory的新实例。

我对实现工厂并不是很熟悉,但我认为您可能想做的是使std::map<std::string, createShapeFunction *> creationFunctions静态,以便ShapeFactory的静态成员函数可以访问它。像你的头文件包含的私有构造函数表明ShapeFactory将是一个单例,所以如果你真的希望它是一个单例,那么使用静态std::map<std::string, createShapeFunction *> creationFunctions就可以了。

根据不修改标题的要求进行编辑:

您可以registerFunctiongetShapeFactory()获取指向工厂的指针。注意我是如何创建一个不是const指针的新指针。这允许您将指针插入到地图中。我不确定如何最好地处理shapeFunction,因为这个方法似乎不太理想,但我不能100%确定这个函数应该做什么。

void ShapeFactory::registerFunction(const std::string &string, const createShapeFunction *shapeFunction)
{
    createShapeFunction* shapeFuncPtr = new createShapeFunction(*shapeFunction);
    ShapeFactory* factory = getShapeFactory();
    factory->creationFunctions.insert(std::pair<string, createShapeFunction*>(string, shapeFuncPtr));
}

getShapeFactory内创建一个创建工厂的静态变量。每次调用此函数时,都会保存此变量的值,因此在第一次调用此函数后,每次都会返回相同的指针。这必须在包含标题的.cpp文件中实现。

ShapeFactory::getShapeFactory()
{
    static ShapeFactory* factory;
    if (factory == NULL)
        factory = new ShapeFactory();
    return factory;
}