おはようモデルをより簡単に開発するにはどうすればいいですか?
現在、私はC++ MVCフレームワークのようなものを開発しています。それはちょうど教育目的のためのものです。私がそのようなことを作り、それを完全に理解し、この(そうでない)美容言語についての新しいことを学ぶことができるかどうかを見ることです。
私は新しいモデルを作るために拡張されるモデルの抽象クラスを持っています。それらはレジスタシングルトンによって登録され、文字列名によってローダークラスでロードされます。
だから、今、空白の新しいモジュールがこのように書かれている:
# myModel.hpp
class myModel: public cinite::core::abstract::Model {
public:
myModel(cinite::core::Loader &_loader): cinite::core::abstract::Model(_loader){};
private:
static cinite::core::registerClass<myModel> __cinite_reg;
};
# myModel.cpp
cinite::core::registerClass<myModel> myModel::__cinite_reg("myModel");
それは足すのかなり多くがありますので、私は
#define CINITE_MODEL_CONSTRUCT(CLASS) \
CLASS(cinite::core::Loader &_loader): cinite::core::abstract::Model(_loader){};
#define CINITE_DEFINE_REGISTRY(CLASS) \
static cinite::core::registerClass<CLASS> __cinite_reg;
#define CINITE_REGISTER(CLASS, NAME) \
cinite::core::registerClass<CLASS> CLASS::__cinite_reg(#NAME);
のように追加するマクロでこれを簡素化することを決定しましただから今のところ全体がこのようになります:
# myModel.hpp
class myModel: public cinite::core::abstract::Model {
public:
CINITE_MODEL_CONSTRUCT(myModel);
private:
CINITE_DEFINE_REGISTRY(myModel);
};
# myModel.cpp
CINITE_REGISTER(myModel, myModel);
明らかに、それははるかに楽になりますr(少なくとも私に)書く。
しかし、まだコンストラクタのことがあります - クラス名を除いてすべてのクラスで同じように見えるので、これを回避する可能性はありますか?デフォルトのabstract :: Modelコンストラクタを使用しますか?誰かが自分のモデルで初期化を必要とし、ローダー全体をバイパスするならば、引数なしで単純な仮想void __init()メソッドを使用します。
最後に、空のモデルを書くのが簡単になるように、デフォルトのabstract :: Modelコンストラクタを引数で使用する方法はありますか? 他のすべてのもの(他のモデル、ドライバ、およびその他のものをロードする)を可能にするものとして、モデルに渡すにはローダーが必要です。
もう1つ、ボーナスの質問:これはいいですか、それとも使用中に恐ろしいものがありますか?ものの好奇心のために
- レジストリ-事がちなみに今
# registry.hpp
namespace cinite {
namespace core {
template <typename T>
abstract::Abstract *abstractCreator(Loader &_loader) {
return new T(_loader);
}
typedef abstract::Abstract* (*abstractCreatorFunc)();
class Registry {
public:
static Registry& getInstance() {
static Registry instance;
return instance;
}
Registry(){};
Registry(Registry const&) = delete;
void operator=(Registry const&) = delete;
const static unsigned int t_abstract = 0;
const static unsigned int t_model = 1;
...
static void registerModel(std::string name, abstractCreatorFunc creator);
static abstractCreatorFunc getModelCreator(std::string name);
...
private:
std::map<std::string, abstractCreatorFunc> _models;
...
};
template<typename T>
struct registerClass {
registerClass(const std::string name) {
switch (T::__regType) {
case Registry::t_model:
Registry::registerModel(name, (abstractCreatorFunc)abstractCreator<T>);
break;
...
}
}
};
}
}
# registry.cpp
using namespace cinite::core;
void Registry::registerModel(std::string name, abstractCreatorFunc creator) {
Registry::getInstance()._models[name] = creator;
}
abstractCreatorFunc Registry::getModelCreator(std::string name) {
Registry ® = Registry::getInstance();
std::map<std::string, abstractCreatorFunc>::iterator it;
it = reg._models.find(name);
if (it == reg._models.end()) {
throw exception::registryException(exception::registryException::MODEL_NOT_REGISTERED, "Model not found in registry (" + name + ")");
}
return (abstractCreatorFunc)it->second;
}
この右のようになります。レジストリのためのソリューションは、this solution(@ヨハネス・シャウブ - litbのおかげで)から来ています。
ええ、それは素晴らしいですね。私が探していたもの –