2016-07-25 68 views
0

晚上好如何讓模型更容易開發

目前我正在開發類似C++ MVC框架的東西。現在只是爲了教育的目的 - 看看我是否可以做出這樣的事情並且完全理解它,並且學習關於這種(而不是)美容語言的新事物。

我有抽象類,將被擴展,使一個新的車型。它們由Register singleton註冊,並通過字符串名稱加載類加載器。

所以,現在,一個空白的新模塊被寫入以這種方式:

# 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(至少對我來說)寫。

但仍然有構造函數的東西 - 我不知道是否有任何可能解決這個問題(因爲這對每個類看起來都是一樣的,除了類名),並使用默認的抽象::模型構造函數?我會用比較簡單的虛擬無效__init()方法,不帶參數,如果有人需要在他的模型中的任何初始化並繞過整個架的事情。

所以,最後,我怎麼能使用它的默認參數::抽象模型構建,使空白車型更容易編寫? 我需要裝載器傳遞到模型,因爲它是使一切其他可能的(加載其他型號,驅動程序和其他的東西)的東西。

而另一位,獎金問題:這樣做看起來不錯,或者是有什麼事情,使得它在使用中可怕嗎?

對於那些好奇心 - 註冊表的事情是這樣的,現在

# 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 &reg = 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)。

回答

1

您可以使用關鍵字using?例如,此代碼編譯:

#include <iostream> 

class A 
{ 
public: 
    A(int a) : mA(a) {} 
    virtual ~A() {} 
    virtual void print() { std::cout << mA << std::endl; } 
protected: 
    int mA; 
}; 

class B : public A 
{ 
public: 
    using A::A; // use the constructor from A 
}; 

int main() 
{ 
    B b(10); 
    b.print(); 
    return 0; 
} 
+0

是的,這看起來不錯。正是我在找什麼 –