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 系统中,
工厂不是“设计模式练习”,
而是“算法可演化性的基础设施”。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1184899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何高效使用论文搜索网站获取学术资源

做科研的第一道坎&#xff0c;往往不是做实验&#xff0c;也不是写论文&#xff0c;而是——找文献。 很多新手科研小白会陷入一个怪圈&#xff1a;在知网、Google Scholar 上不断换关键词&#xff0c;结果要么信息过载&#xff0c;要么完全抓不到重点。今天分享几个长期使用的…

POF|清华大学张宇飞团队:采用数据驱动湍流模型的三维增升装置模拟

采用数据驱动湍流模型的三维增升装置模拟 Three-dimensional high-lift configuration simulation usingdata-driven turbulence model 张绍广&#xff0c;吴辰禹&#xff0c;张宇飞* 清华大学&#xff0c;航天航空学院&#xff0c;北京100084 引用格式&#xff1a; Liao H,…

配电不透明,管理就无从谈起,这正是很多企业大楼的现状

安科瑞刘鸿鹏172 一 ⑥⑨⑦② 一 5322在企业大楼的配电系统中&#xff0c;用电规模不断扩大、负载类型日趋复杂&#xff0c;传统断路器“只分合、不感知”的局限性正逐渐显现。运维人员往往只能在故障发生后被动处理&#xff0c;缺乏对回路运行状态的持续掌握&#xff0c;这不仅…

❿⁄₁₄ ⟦ OSCP ⬖ 研记 ⟧ 密码攻击实践 ➱ 传递Net-NTLMv2哈希

郑重声明&#xff1a;本文所涉安全技术仅限用于合法研究与学习目的&#xff0c;严禁任何形式的非法利用。因不当使用所导致的一切法律与经济责任&#xff0c;本人概不负责。任何形式的转载均须明确标注原文出处&#xff0c;且不得用于商业目的。 &#x1f50b; 点赞 | 能量注入…

UL 认证光伏电表如何满足北美逆变器并网要求?

安科瑞刘鸿鹏在北美光伏市场中&#xff0c;无论是分布式屋顶光伏&#xff0c;还是工商业逆变器并网项目&#xff0c;对电能计量与并网监测的要求始终处在一个较高标准。并网合规、发电量核算、能量流向判定以及与逆变器系统的稳定通信&#xff0c;都是光伏系统能否顺利运行的基…

企业级光储充电站能量协调控制系统的设计与应用

安科瑞刘鸿鹏 摘要随着企业级光伏、储能及电动汽车充电设施的集中建设&#xff0c;光储充电站逐渐从单一能源设施演变为具备多源接入、多目标运行的复杂用能系统。如何在保障安全运行的前提下&#xff0c;实现新能源有效消纳、储能经济调度及充电负荷柔性管理&#xff0c;成为企…

2026版Java面试题库及答案解析

今年的行情&#xff0c;让招聘面试变得雪上加霜。已经有不少大厂&#xff0c;如腾讯、字节跳动的招聘名额明显减少&#xff0c;面试门槛却一再拔高&#xff0c;如果不用心准备&#xff0c;很可能就被面试官怼得哑口无言&#xff0c;甚至失去了难得的机会。 现如今&#xff0c;…

MATLAB 神经网络从入门到实战:零基础教程

一、神经网络核心概念与MATLAB优势 神经网络是模拟人脑神经元结构的数学模型,通过数据训练自动学习特征规律,广泛应用于分类、回归、预测等场景。MATLAB作为工程领域主流工具,其Neural Network Toolbox(神经网络工…

Java多线程编程:使用场景与实现详解

Java多线程编程&#xff1a;使用场景与实现详解 一、什么是多线程 多线程是指在一个程序中同时运行多个线程&#xff0c;每个线程可以独立执行不同的任务。Java从语言层面提供了强大的多线程支持&#xff0c;使得并发编程变得相对简单。 二、常见使用场景 1. 提高程序响应速度 …

疆鸿智能ETHERCAT从站转DEVICENET主站详细解读,建议点赞收藏术语

疆鸿智能ETHERCAT从站转DEVICENET主站详细解读&#xff0c;建议点赞收藏 术语 DeviceNet&#xff1a;DeviceNet是ODVA推出基于CAN的一种通讯规范 EtherCAT&#xff1a;EtherCAT&#xff08;以太网控制自动化技术&#xff09;是一个开放架构&#xff0c;以以太网为基础的现场…

读懂价格背后的语言:如何用速卖通价格历史图表,预判市场趋势与库存风险

当你在速卖通上看到一款常销产品的价格突然下跌&#xff0c;一个紧迫的问题随之而来&#xff1a;这是供应商为清仓或冲量进行的短期促销&#xff0c;还是预示市场饱和、竞争加剧的长期降价趋势&#xff1f;判断失误的代价是高昂的——若误将趋势当促销而大量补货&#xff0c;可…

免费查文献的网站推荐:实用且可靠的文献查询平台汇总

做科研的第一道坎&#xff0c;往往不是做实验&#xff0c;也不是写论文&#xff0c;而是——找文献。 很多新手科研小白会陷入一个怪圈&#xff1a;在知网、Google Scholar 上不断换关键词&#xff0c;结果要么信息过载&#xff0c;要么完全抓不到重点。今天分享几个长期使用的…

救命神器!专科生必看10个AI论文平台测评与推荐

救命神器&#xff01;专科生必看10个AI论文平台测评与推荐 专科生必备的AI论文工具测评指南 在当前学术竞争日益激烈的背景下&#xff0c;专科生在撰写论文时常常面临内容构思困难、格式规范不熟悉、查重压力大等挑战。为帮助广大专科生高效完成论文写作任务&#xff0c;笔者基…

计算机毕业设计springboot宠物信息管理系统 基于Spring Boot的宠物信息综合管理系统设计与实现 Spring Boot框架下的宠物信息管理平台开发

计算机毕业设计springboot宠物信息管理系统8nh44 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着宠物市场的蓬勃发展&#xff0c;宠物信息管理的需求也日益增长。传统的宠物…

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

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

2026年轨道轴承市场报告:行业现状、驱动因素与未来发展趋势深度解析

轨道轴承&#xff0c;又称铁路轴承或轨道交通专用滚动轴承&#xff0c;主要用于支撑车轴并减少轮轨之间的摩擦阻力。与普通工业轴承相比&#xff0c;轨道轴承需承受更高的载荷、更频繁的冲击以及极端温差环境&#xff0c;因此对材料强度、密封性、润滑性能和疲劳寿命有严苛要求…

贵州省考报名今天开始!详细报名流程秒懂

贵州的考公人集合啦&#xff01;2026贵州省考报名通道已经正式开启&#x1f51b; 从照片调整到选岗缴费&#xff0c;我把全流程都给你们整理好啦&#x1f447;⏰ 关键时间节点 ✅ 报名时间&#xff1a;1月19日9:00—1月23日 ✅ 初审时间&#xff1a;1月19日—1月25日 ✅ 缴费时…

计算机毕业设计springboot网络云盘系统的设计与实现 基于Spring Boot框架的网络云存储系统开发与实现 Spring Boot驱动的网络云盘系统设计与开发实践

计算机毕业设计springboot网络云盘系统的设计与实现_10f66&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着信息技术的飞速发展&#xff0c;网络云盘系统已成为现代信息管理的…

构筑价格护城河:如何用速卖通价格历史监控,第一时间狙击低价跟卖

你花费数月打磨详情、积累评价&#xff0c;终于将一款产品推至热销榜。但很快&#xff0c;订单增长开始停滞&#xff0c;利润空间被莫名压缩。当你点开产品页面&#xff0c;发现下方悄然出现了数个“Similar item”&#xff0c;以低于你10%-20%的价格&#xff0c;蚕食着你的流量…

英文文献检索的方法与技巧:提升学术研究效率的关键步骤

做科研的第一道坎&#xff0c;往往不是做实验&#xff0c;也不是写论文&#xff0c;而是——找文献。 很多新手科研小白会陷入一个怪圈&#xff1a;在知网、Google Scholar 上不断换关键词&#xff0c;结果要么信息过载&#xff0c;要么完全抓不到重点。今天分享几个长期使用的…