• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

兵棋研究所

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

开发随笔1 - 现代C++对象工厂模式实现

这篇文章将介绍一个基于现代C++特性的对象工厂实现方案,该方案采用了模板元编程和静态注册技术,为创建对象提供了灵活且类型安全的机制。

核心设计理念

这个工厂模式实现包含三个关键组件:

  1. ObjectFactory模板类‌:通用的工厂基类,提供对象注册和创建功能
  2. AutoRegister辅助类‌:自动注册具体产品类的工具类
  3. REGISTER_PRODUCT宏‌:简化注册过程的语法糖


技术亮点

  1. 类型安全‌:通过模板参数确保产品类型匹配
  2. 自动注册‌:利用静态变量初始化实现零配置注册
  3. 内存管理‌:使用shared_ptr自动管理对象生命周期
  4. 单例模式‌:Meyer's singleton保证静态数据安全初始化
  5. 简洁接口‌:提供清晰的工厂API(register/create/clear)

代码

#include <functional>
#include <map>
#include <memory>

template<class AbstractProduct, class ProductID = std::string>
class ObjectFactory
{
public:
    using ProductPtr = std::shared_ptr<AbstractProduct>;
    using Builder = std::function<ProductPtr()>;

    static void registerBuilder(const ProductID& id, Builder builder)
    {
        getBuilders().insert_or_assign(id,builder);
    }

    template<typename ConcreteProduct,typename... Args>
    static void registerBuilder(const ProductID& id)
    {
        registerBuilder(id,[]()
        {
            return std::make_shared<ConcreteProduct>();
        });
    }

    static ProductPtr create(const ProductID& id)
    {
        auto it = getBuilders().find(id);
        return it != getBuilders().end() ? it->second() : nullptr;
    }

    static void clear()
    {
        getBuilders().clear();
    }
private:
    static std::unordered_map<ProductID, Builder>& getBuilders()
    {
        static std::unordered_map<ProductID, Builder> instance;
        return instance;
    }
};

template<class AbstractProduct, class ConcreteProduct, class ProductID = std::string>
class AutoRegister
{
public:
    explicit AutoRegister(const ProductID& id)
    {
        ObjectFactory<AbstractProduct,ProductID>::template registerBuilder<ConcreteProduct>(id);
    }
};

#define REGISTER_PRODUCT(AbstractType, ConcreteType, id) \
    namespace\
    { \
        AutoRegister<AbstractType, ConcreteType> auto_reg_##ConcreteType(id); \
    }

使用方式

using namespace std;

class Animal
{
public:
    virtual void say() = 0;
};

class Cat : public Animal
{
public:
    Cat()
    {
    }
    
    void say()
    {
        std::cout<<"i am cat"<<std::endl;
    }
private:
};

class Dog : public Animal
{
public:
    void say()
    {
        std::cout<<"i am dog"<<std::endl;
    }
};

REGISTER_PRODUCT(Animal, Cat,"Cat")
REGISTER_PRODUCT(Animal, Dog,"Dog")

int main()
{
    auto animal1 = ObjectFactory<Animal,std::string>::create("Cat");
    animal1->say();

    auto animal2 = ObjectFactory<Animal,std::string>::create("Dog");
    animal2->say();
    return 0;
}

 

posted on 2025-10-15 15:32  ccsdu2004  阅读(8)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3