0

我是 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;
}
4

2 回答 2

2

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

于 2013-03-30T20:28:53.210 回答
1

ShapeFactory我看到的一个问题是您正在从静态函数访问一个私有变量。静态函数与 a 的特定实例无关,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;
}
于 2013-03-30T20:30:56.890 回答