DynObj.h
#ifndef __DYNOBJ_H #define __DYNOBJ_H #include <map> #include <string> using Constructor = void* (*)(); //定义一个函数指针 class CObjFactory { private: //创建一个全局map容器, string->key, 存储 类名和函数 inline static std::map<std::string, Constructor>& createSMapContainer() { static std::map<std::string, Constructor> instance; return instance; } public: static void registerClass(std::string className, Constructor constructor) { createSMapContainer()[className] = constructor; } static void* createObject(const std::string& className) { Constructor constructor = nullptr; if (createSMapContainer().find(className) != createSMapContainer().end()) constructor = createSMapContainer().find(className)->second; if (constructor == nullptr) return nullptr; return (*constructor)(); } }; #define REG_CLASS(className)\ class className##Helper {\ public:\ className##Helper() {\ CObjFactory::registerClass(#className, className##Helper::createPtr);\ }\ \ static void* createPtr() {\ return new className;\ }\ };\ className##Helper className##helper; #endif // !__DYNOBJ_H
api.h
#pragma once #include <string> #include <iostream> #include "DynObj.h" std::string SClassName = "ImpleTwo"; class Api { protected: Api() {} //屏蔽构造函数,体现接口 public: virtual void test(std::string s) = 0; //纯虚函数 }; class ImpleOne : public Api { public: void test(std::string s) { std::cout << "ImpleOne: " << s; } }; class ImpleTwo : public Api { public: void test(std::string s) { std::cout << "ImpleTwo: " << s; } }; class AutoFactory { public: static Api* createApi() { Api* pApi = nullptr; pApi = static_cast<Api*>(CObjFactory::createObject(SClassName)); return pApi; } };
main.cpp
#include <iostream> #include <string> #include "api.h" REG_CLASS(ImpleTwo) int main(void) { Api* p = AutoFactory::createApi(); p->test("简单工厂"); return 0; }
上面仅通过REG_CLASS(ImpleOne)和std::string SClassName = "ImpleOne";的更改就可以控制客户端到底使用了哪个类对象。而对于客户端而言,自己只知道创建了一个对象,而对于这个对象的实现细节一无所知,只知道怎么使用其中的方法就行了。