Reputation: 727
I'm new to this factory pattern in C++ and I was given the header yet while trying to implement one of the methods I am getting the following error:
Invalid use of member 'creationFunctions' in static member function
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;
}
Upvotes: 0
Views: 7269
Reputation: 2281
One problem I see is that you are accessing a variable private to ShapeFactory
from a static function. Static functions are not tied to a specific instance of a ShapeFactory
so you cannot access non-static private variables. Another side effect of this is that this
is not defined in the context of static functions. Each time you create an instance of ShapeFactory
a new instance of std::map<std::string, createShapeFunction *> creationFunctions
is created for each ShapeFactory
.
I'm not very familier with implementing factories, but I think what you might want to do is make std::map<std::string, createShapeFunction *> creationFunctions
static so that it can be accessed by the static member functions of ShapeFactory
. A private constructor like what your header file contains suggests that ShapeFactory
will be a singleton and so if you really want it to be a singleton, making std::map<std::string, createShapeFunction *> creationFunctions
by static should be okay.
Edit based on requirement to not modify header:
You can have registerFunction
get a pointer to a factory from getShapeFactory()
. Notice how I create a new pointer that is not a const pointer. This allows you to insert the pointer into the map. I'm not sure how best to handle shapeFunction
as this method seems like it may not be ideal, but I'm not 100% sure what this function is supposed to do.
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));
}
Have a static variable within getShapeFactory
that creates a factory. The value of this variable will get saved each time this function is called so after the first call of this function the same pointer will be returned each time. This has to be implemented in a .cpp file that contains your header.
ShapeFactory::getShapeFactory()
{
static ShapeFactory* factory;
if (factory == NULL)
factory = new ShapeFactory();
return factory;
}
Upvotes: 1
Reputation: 4381
You can't access non-static members of a class from a static member function. In your example the probably best idea would be to make all member functions non-static, except "getShapeFactory" which would then act as Mayer's singleton generator...
Upvotes: 2