0

私は C++ でこのファクトリ パターンを初めて使用し、次のエラーが発生するメソッドの 1 つを実装しようとしているときに、まだヘッダーが与えられました。

静的メンバー関数でのメンバー '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私が目にする問題の 1 つは、静的関数から変数 private にアクセスしていることです。静的関数は の特定のインスタンスに関連付けられていないため、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;
}
于 2013-03-30T20:30:56.890 に答える