程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++中實現自動注冊的工廠

C++中實現自動注冊的工廠

編輯:C++入門知識

C++中實現自動注冊的工廠


很長時間沒有更新博客了,不是博主懶,是因為博主在幫研究生妹子弄碩士論文,定位方面的,被imu,行人航跡,激光匹配各種虐,不說了,都是淚。

Factory模式,在工程中多用了創建派生類實例,內部一般使用switch-case根據不同的key去創建不同的派生類對象。

switch(Key) {
    case A: 
        return new A;
    case B:
        return new B;

    ...
}

對於繼承體系簡單的,這種還可以,如果對於一個復雜的體系,比如一個命令系統,最後其有100多個業務命令的類,那難道你還想把switch-case寫成和懶婆娘的裹腳布一樣,又臭又長,顯然是不可以的,今天我們就來實現一個自動注冊的工廠。
其實這個設計思路我在很早之前就看過,第一次好像是在cpp博客,第二次是在csdn,最近cpp社區“行知一”又看見了,但是他們那個只是一個demo代碼,雖然這裡我們只是簡單的寫寫,但是盡量讓其可以直接使用。
其實思路很簡單,借助於map數據結構,標示類唯一的身份標記作為map的key,而value則是一個lambda表達式,其用來產生類實例。
factory的代碼如下:

#ifndef FACTORY
#define FACTORY


#include 
#include
#include 

using namespace std;

template 
class Factory
{
public:


    typedef T type_value;

    template 
    struct register_h
    {
        register_h(const K& key)
        {
            Factory::instance()->m_creators[key] = []{ return new N; };
        }
    };


    static auto instance() -> Factory*
    {
        static Factory f;
        return &f;
    }

    auto creat(const K& key) -> T*
    {
        T* re = NULL;
        auto ite = m_creators.find(key);
        if (ite != m_creators.end()) {
            re = (ite->second)();
        }
        return re;
    }

    static auto produce(const K& key) -> T*
    {
        return Factory::instance()->creat(key);
    }

private:
    Factory() {}
    Factory(const Factory&) = delete;
    Factory(Factory&&) = delete;
    Factory& operator =(const Factory&) = delete;
    std::map> m_creators;
};


#define CLASS_NAME(CLASS) #CLASS



#endif // FACTORY

默認使用string來作為鍵值。register_h類是很重要的一步,我們借組於其的實例化來完成注冊動作。
其他的一些函數就是一些基礎的功能,無非就是查找操作。
簡單的使用demo,Object是我們的基類,然後其有一個Widget子類。

#ifndef OBJECT
#define OBJECT

#include "factory.h"


class Object
{
public:
    virtual ~Object() {}

};


#define FACTORY_OBJECT Factory
#ifndef WIDGET_H
#define WIDGET_H

#include "object.h"


class Widget : public Object
{
public:
    Widget();
};

#endif // WIDGET_H
#include "widget.h"

Widget::Widget()
{

}


REGISTER_OBJECT_CLASS(Widget);

REGISTER_OBJECT_CLASS(Widget);這句代碼完成了注冊,其實例化一個命名為__WidgtFactory對象,在構造函數中現實了自動注冊。

main.cpp

#include 
#include "widget.h"

using namespace std;







int main()
{
    Widget *p = static_cast(FACTORY_OBJECT::produce("Widget"));
    FACTORY_OBJECT::type_value* p1 = FACTORY_OBJECT::produce("Text");
    std::cout << p1;
    std::cout << "\n-----------------";
    std::cout << p;
    std::cout << "Hello World!" << std::endl;
    delete p;
    delete p1;
    return 0;
}

object.h中的幾個宏封裝了細節。但是比如

#ifndef MESSAGE
#define MESSAGE

#include "factory.h"

class Message
{

};



#define FACTORY_MESSAGE Factory


#define REGISTER_MESSAGE_CLASS_KEY(CLASS, KEY) \
    FACTORY_MESSAGE::register_h __##CLASS(KEY)


#define REGISTER_MESSAGE_CLASS(CLASS) \
    REGISTER_MESSAGE_CLASS_KEY(CLASS, CLASS_NAME(CLASS))


#endif // MESSAGE

新的一個類繼承體系,宏寫了一遍,但是這些宏的動作十分的相似,還是可以再抽象一下。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved