さまざまなソースからの助けを借りて、ファクトリが派生クラスに依存しない単純なテンプレートベースのファクトリパターンクラスを作成することができました。ここにコードをアップロードしました:https://github.com/piyushsoni/FactoryPattern。それは完璧ではないかもしれませんが、この例では私の驚きにもかかわらず動作します。これを私たちの大きな実際のコードベースでほぼ同じように使用すると、のいくつかのほんの少しののための 'DerivedFactory'のコンストラクタが呼び出され、他のものについては完全に無視されます。 DerivedFactoryオブジェクトにアクセスできる静的関数を定義してから実際にを呼び出すと、派生したファクトリオブジェクトを左辺値に割り当てることができます(必要なし)。私はmain.cppでそれらを作成してください)。コンパイラがここで不必要な最適化を行っているようです。スタティックオブジェクトのコンストラクタがこのファクトリコード(C++)で呼び出されないのはなぜですか?
このサンプルプロジェクトはVC 15でテストされていますが、実際のコードベースではC++ 11機能を有効にしたインテル®コンパイラーを使用しています(WindowsではMSVC11、Linuxではgccを使用)。 MSVC11とGCC 4.8以降で、これらの単純な静的オブジェクトが毎回作成されるように、どうすれば修正できますか?
編集:私はきれいな質問を保つために、ここですべてのコードを書くと、1つの公共の場所でソースコードを置くことが、フィードバックに今ここにそれをやって(そしてそれが閉じ避けるために)避けたかったです。この単純なコードが実際に動作していると書いておきたいが、Windows上でMSVC11を内部的に使用しているインテルコンパイラを使用してコンパイルされた商用コードに入れると、ほとんど同じコードが動作しない。他の質問がある場合は、コメントでそれらを尋ねてください。私は答えようとします。答えを出す前に、質問を閉じないようにしてください。私は上に直面している正確な問題を書いています。ここで
は、ファイルは次のとおりです。
ShapeFactory.h
#pragma once
#include <map>
using namespace std;
#include "Shape.h"
#define REGISTER_CLASS(objectClass) static DerivedFactory<objectClass> shape##objectClass(Type_ ## objectClass);
class Shape;
class ShapeFactory;
typedef map<ShapeType, ShapeFactory*> mapTypeShapeFactoryByType;
class ShapeFactory
{
private:
mapTypeShapeFactoryByType mapShapeTypeByFactory;
protected:
ShapeFactory() {}
virtual Shape* Create() { return NULL; }
private:
ShapeFactory(const ShapeFactory&);
public:
virtual ~ShapeFactory() {}
static ShapeFactory& GetShapeFactory();
Shape* CreateShape(ShapeType type);
virtual void DestroyShape(Shape* object) { delete object; object = nullptr; }
void RegisterFactory(ShapeType type, ShapeFactory* factory);
};
template<typename ShapeClass>
class DerivedFactory : public ShapeFactory
{
public:
DerivedFactory(ShapeType type)
{
ShapeFactory::GetShapeFactory().RegisterFactory(type, this);
}
~DerivedFactory() {}
Shape* Create() { return new ShapeClass(); }
};
ShapeFactory.cpp
#include "ShapeFactory.h"
//mapTypeShapeFactoryByType ShapeFactory::mapShapeTypeByFactory;
//ShapeFactory* ShapeFactory::mInstance = NULL;
ShapeFactory& ShapeFactory::GetShapeFactory()
{
static ShapeFactory instance;
return instance;
}
Shape * ShapeFactory::CreateShape(ShapeType type)
{
if (mapShapeTypeByFactory.find(type) != mapShapeTypeByFactory.end())
return mapShapeTypeByFactory[type]->Create();
else
return nullptr;
}
void ShapeFactory::RegisterFactory(ShapeType type, ShapeFactory * factory)
{
mapShapeTypeByFactory[type] = factory;
}
Shape.h
#pragma once
#include <string>
using namespace std;
enum ShapeType
{
Type_Unknown,
Type_Circle,
Type_Rectangle,
Type_Polygon
};
class Shape
{
std::string name;
public:
virtual ~Shape() {}
virtual ShapeType GetType() { return Type_Unknown; }
};
Rectangle.h
#pragma once
#include "Shape.h"
#include <iostream>
using namespace std;
class Rectangle : public Shape
{
public:
Rectangle();
virtual ~Rectangle();
virtual ShapeType GetType() { return Type_Rectangle; }
private:
float points[4][3];
};
Rectangle.cpp
#include "Rectangle.h"
#include "ShapeFactory.h"
static DerivedFactory<Rectangle> RectangleFactory(Type_Rectangle);
Rectangle::Rectangle()
{
cout << "The factory created new Rectangle! \n";
}
Rectangle::~Rectangle()
{
cout << "The Rectangle object was destroyed \n";
}
Circle.h
#pragma once
#include "Shape.h"
#include <iostream>
using namespace std;
class Circle : public Shape
{
public:
Circle();
virtual ~Circle();
virtual ShapeType GetType() { return Type_Circle; }
private:
float center[3];
float radius;
};
Circle.cpp
#include "Circle.h"
#include "ShapeFactory.h"
static DerivedFactory<Circle> CircleFactory(Type_Circle);
Circle::Circle()
{
cout << "The factory created new Circle! \n";
}
Circle::~Circle()
{
cout << "The Circle object was destroyed \n";
}
main.cppに
#include <iostream>
#include <string>
#include <map>
#include "ShapeFactory.h"
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
using namespace std;
int main()
{
ShapeFactory& factory = ShapeFactory::GetShapeFactory();
Circle* vec = (Circle*)factory.CreateShape(Type_Circle);
cout << "Object type is : " << vec->GetType() <<"\n";
factory.DestroyShape(vec);
Rectangle* con = (Rectangle*)factory.CreateShape(Type_Rectangle);
cout << "Object type is : " << con->GetType() << "\n";
factory.DestroyShape(con);
getchar();
return 0;
}
感謝!!
読者がこれを試すことができるように、質問自体には最小限の完全な例を記入してください。現時点で**関連する例がない**として閉じるために投票してください。 –
@ Cheersandhth.-Alf:複数のファイルがあるのでここで質問をするためにgithubにプロジェクトをアップロードしましたが、ここでそれらをすべて追加するように編集します。しかし、著者が質問を編集できるようにするために数時間も待つことなく、質問をすばやく「閉じる」という熱意を理解していません。何度も何度もリクエストされた編集が行われていますが、誰かが閉鎖された質問に訪れました。それは初心者を助ける方法ではありません。 –