news 2026/4/18 6:26:03

C++(C++17/20)最佳工厂写法和SLAM应用综合示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++(C++17/20)最佳工厂写法和SLAM应用综合示例

现代 C++(C++17/20)下的最佳工厂写法


一、现代 C++ 工厂设计的基本原则

在 C++17/20 下,好的工厂写法通常满足:

  1. RAII + 明确所有权

    • 返回std::unique_ptr<T>为默认
  2. switch/ 无 RTTI

  3. 支持扩展而不修改(OCP)

  4. 构造逻辑与业务逻辑分离

  5. 尽量零运行期成本或可控成本


二、最推荐写法:注册式工厂(Registry-based Factory)

90% 工程项目的首选

1. 基本结构

classBase{public:virtual~Base()=default;virtualvoidrun()=0;};usingCreator=std::function<std::unique_ptr<Base>()>;
classFactory{public:staticFactory&instance(){staticFactory f;returnf;}voidregisterCreator(std::string key,Creator creator){creators_.emplace(std::move(key),std::move(creator));}std::unique_ptr<Base>create(conststd::string&key)const{returncreators_.at(key)();}private:std::unordered_map<std::string,Creator>creators_;};

2. 自动注册(推荐)

template<typenameT>structAutoRegister{AutoRegister(conststd::string&key){Factory::instance().registerCreator(key,[]{returnstd::make_unique<T>();});}};
classImplA:publicBase{public:voidrun()override{}};staticAutoRegister<ImplA>regA("A");

优点

  • 零侵入
  • 插件友好
  • 新增类型无需改工厂

3. 为什么这是“现代”写法?

  • 使用unique_ptr明确所有权
  • Lambda 消除样板代码
  • static局部变量保证线程安全(C++11+)
  • 完全 OCP

三、带参数的现代工厂写法(非常常见)

1. 问题

构造函数有参数:

ImplA(intw,doubles);

2. 推荐方案:参数对象(Parameter Object)

structConfig{intwidth;doublescale;};
usingCreator=std::function<std::unique_ptr<Base>(constConfig&)>;
classFactory{public:voidregisterCreator(std::string key,Creator c){creators_[key]=std::move(c);}std::unique_ptr<Base>create(conststd::string&key,constConfig&cfg)const{returncreators_.at(key)(cfg);}private:std::unordered_map<std::string,Creator>creators_;};
Factory::instance().registerCreator("A",[](constConfig&cfg){returnstd::make_unique<ImplA>(cfg.width,cfg.scale);});

工程价值

  • 构造参数可扩展
  • 工厂接口稳定
  • 不破坏 ABI

四、C++20 改进:Concept + 工厂

适合大型工程 / 库级代码

template<typenameT>conceptProduct=std::derived_from<T,Base>&&std::default_initializable<T>;
template<Product T>voidregisterType(std::string key){Factory::instance().registerCreator(std::move(key),[]{returnstd::make_unique<T>();});}

收益

  • 编译期约束
  • 错误更早暴露
  • 接口自文档化

五、高性能版本:无std::function

当工厂在热路径中被频繁调用:

1. 问题

  • std::function可能引入堆分配
  • 虚调用 + 间接跳转

2. 解决方案:函数指针 / 模板表

usingCreator=std::unique_ptr<Base>(*)();
template<typenameT>std::unique_ptr<Base>createImpl(){returnstd::make_unique<T>();}
creators_["A"]=&createImpl<ImplA>;

权衡

  • 性能更优
  • 灵活性略降
  • 适合内核模块

六、编译期工厂(零运行期开销)

当类型集合在编译期固定

template<typenameT>std::unique_ptr<Base>create(){returnstd::make_unique<T>();}

调用方:

autoobj=create<ImplA>();

适合

  • 算法内核
  • 无运行期配置
  • 性能敏感路径

七、工厂 + 插件系统(dlopen)

典型结构:

Factory (主程序) ↑ PluginA.so → register("A") PluginB.so → register("B")

插件加载时执行:

extern"C"voidregisterPlugin(){Factory::instance().registerCreator("A",[]{returnstd::make_unique<ImplA>();});}

这是现代大型 C++ 系统最常见的用法之一。


八、现代 C++ 工厂的反例(请避免)

返回裸指针

Base*create();

工厂中塞业务逻辑

createAndRunAndValidate();

构造参数散落

create(int,int,double,bool);

九、快速选型总结

场景推荐方案
配置驱动注册式工厂
插件系统自动注册
性能敏感函数指针工厂
编译期固定模板工厂
API/SDKConcept + Factory

十、总结

现代 C++ 的工厂模式,本质是:
用类型系统 + RAII + 注册机制,
将“变化”限制在最小边界内。


一个真实 SLAM 模块的完整工厂实现

示例模块:FeatureExtractor


一、模块目标与设计边界

1. 目标

  • 支持多种特征提取算法(ORB / FAST / SuperPoint)
  • 通过配置文件选择实现
  • 不修改核心逻辑即可新增算法
  • 生命周期与 SLAM 系统一致

2. 架构位置(典型 SLAM)

Frontend ├── FeatureExtractor ← 工厂创建 ├── FeatureMatcher └── Tracker

FeatureExtractor 是典型“策略可替换模块”


二、接口定义

feature_extractor.h

#pragmaonce#include<vector>#include<opencv2/core.hpp>structFeature{cv::KeyPoint keypoint;cv::Mat descriptor;};classFeatureExtractor{public:virtual~FeatureExtractor()=default;virtualstd::vector<Feature>extract(constcv::Mat&image)=0;};

设计要点

  • 纯接口
  • 无构造参数
  • 不暴露具体实现细节

三、参数对象(Config)

extractor_config.h

#pragmaonce#include<string>structExtractorConfig{std::string type;// "ORB" / "FAST" / ...intmax_features=1000;floatscale_factor=1.2f;intlevels=8;};

关键工程点

  • 构造参数集中
  • 新增参数不破坏工厂接口
  • 易于 YAML / JSON 映射

四、具体实现(变化层)

orb_extractor.h

#pragmaonce#include"feature_extractor.h"#include"extractor_config.h"classORBExtractorfinal:publicFeatureExtractor{public:explicitORBExtractor(constExtractorConfig&cfg);std::vector<Feature>extract(constcv::Mat&image)override;private:intmax_features_;floatscale_factor_;intlevels_;};

orb_extractor.cpp

#include"orb_extractor.h"ORBExtractor::ORBExtractor(constExtractorConfig&cfg):max_features_(cfg.max_features),scale_factor_(cfg.scale_factor),levels_(cfg.levels){}std::vector<Feature>ORBExtractor::extract(constcv::Mat&image){std::vector<Feature>features;// ORB extraction logic...returnfeatures;}

五、工厂定义(核心)

feature_extractor_factory.h

#pragmaonce#include<memory>#include<unordered_map>#include<functional>#include<string>#include"feature_extractor.h"#include"extractor_config.h"classFeatureExtractorFactory{public:usingCreator=std::function<std::unique_ptr<FeatureExtractor>(constExtractorConfig&)>;staticFeatureExtractorFactory&instance();voidregisterCreator(conststd::string&type,Creator creator);std::unique_ptr<FeatureExtractor>create(constExtractorConfig&cfg)const;private:FeatureExtractorFactory()=default;std::unordered_map<std::string,Creator>creators_;};

feature_extractor_factory.cpp

#include"feature_extractor_factory.h"#include<stdexcept>FeatureExtractorFactory&FeatureExtractorFactory::instance(){staticFeatureExtractorFactory factory;returnfactory;}voidFeatureExtractorFactory::registerCreator(conststd::string&type,Creator creator){creators_[type]=std::move(creator);}std::unique_ptr<FeatureExtractor>FeatureExtractorFactory::create(constExtractorConfig&cfg)const{autoit=creators_.find(cfg.type);if(it==creators_.end()){throwstd::runtime_error("Unknown FeatureExtractor type: "+cfg.type);}returnit->second(cfg);}

六、自动注册(工程关键技巧)

extractor_register.h

#pragmaonce#include"feature_extractor_factory.h"template<typenameT>structExtractorRegistrar{ExtractorRegistrar(conststd::string&type){FeatureExtractorFactory::instance().registerCreator(type,[](constExtractorConfig&cfg){returnstd::make_unique<T>(cfg);});}};

orb_register.cpp

#include"orb_extractor.h"#include"extractor_register.h"staticExtractorRegistrar<ORBExtractor>reg_orb("ORB");

重要工程特性

  • 无需修改工厂

  • 新算法只需:

    • 新类
    • .cpp注册文件

七、系统使用方式

ExtractorConfig cfg;cfg.type="ORB";cfg.max_features=1500;autoextractor=FeatureExtractorFactory::instance().create(cfg);autofeatures=extractor->extract(image);

此处 Frontend 完全不知道 ORB 的存在


八、为什么这是“真实 SLAM 工厂实现”

1. 满足真实工程需求

  • 算法频繁切换
  • 配置驱动
  • 生命周期清晰
  • 可测试、可扩展

2. 与 SLAM 实际复杂度匹配

  • 不引入 DI 框架
  • 不过度模板化
  • 不牺牲可读性

3. 易于扩展为插件系统

libslam_core.so liborb_extractor.so libsuperpoint_extractor.so

每个插件在加载时完成注册。


九、常见坑(真实踩坑总结)

1. 静态初始化顺序问题

问题: 注册对象在工厂之前初始化
方案: 使用instance()的局部静态


2. 工厂里塞逻辑

问题: 工厂决定参数
方案: 参数由 Config 决定


3. 返回裸指针

问题: 生命周期不明确
方案:std::unique_ptr


十、总结

在真实 SLAM 系统中,
工厂不是“设计模式练习”,
而是“算法可演化性的基础设施”。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 3:05:29

一次分析变批量生产:OpenCSG公益课方法

由特许全球金融科技师CGFT认证项目&#xff08;Chartered Global FinTech) 、模速空间与OpenCSG&#xff08;开放传神&#xff09;联合推出《普通人的AI掘金课——6天学会&#xff0c;马上能用》系列直播课程&#xff0c;最实用的一点是&#xff1a;它不把AI当“灵感工具”&…

作者头像 李华
网站建设 2026/4/15 20:52:58

【量化基础】数据驱动决策:从零接入StockTV实时行情API

【量化基础】数据驱动决策&#xff1a;从零接入StockTV实时行情API 在算法主导交易的今天&#xff0c;数据质量直接决定了策略的生死。本文将从量化基础切入&#xff0c;手把手教你如何用Python对接专业级数据源StockTV&#xff0c;为你的策略注入毫秒级竞争力。 一、量化交易的…

作者头像 李华
网站建设 2026/4/7 3:15:56

突破C2Q瓶颈,MLGO微算法科技高性能可重构计算机实现量子算法真实级仿真,推动量子仿真进入新阶段

在量子计算技术快速发展的当下&#xff0c;如何以现实可行的方式进行量子算法的验证与评估&#xff0c;成为产业界与科研界共同面临的重要挑战。量子硬件虽然已进入噪声中型量子&#xff08;NISQ&#xff09;阶段&#xff0c;但其量子比特数量、纠缠深度和抗噪性能依然受到严苛…

作者头像 李华
网站建设 2026/3/18 11:40:24

python鲜花销售系统 网上鲜花商城系统商家

目录鲜花销售系统摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;鲜花销售系统摘要 网上鲜花商城系统为商家提供高效便捷的线上销售平台&#xff0c;整合订单管理、库存跟踪、客户服务等…

作者头像 李华
网站建设 2026/3/15 21:37:10

基于python+Vue的游戏装备交易商城系统

目录系统概述技术架构核心功能创新与优化应用价值开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;系统概述 该系统基于Python后端与Vue.js前端构建&#xff0c;专为游戏装备交易设计&#x…

作者头像 李华
网站建设 2026/4/17 6:57:47

广西产业带背后的真实情况:不要再把“东盟展厅”当成是源头工厂了!

作为中国和东盟合作的前沿地带&#xff0c;广西壮族自治区正在全力打造具有特色的产业集群&#xff1a;南宁的电子信息产业、柳州的新能源汽车产业、玉林的香料陶瓷产业、钦州的燕窝荔枝产业、崇左的东盟水果产业等等……政策带来的发展红利和优越的地理位置优势相互叠加&#…

作者头像 李华