我是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;
}
答案 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
就可以了。
根据不修改标题的要求进行编辑:
您可以registerFunction
从getShapeFactory()
获取指向工厂的指针。注意我是如何创建一个不是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;
}