C++实现类Simulink/LabView持续运行框图的设计模式建议
类Simulink/LabView框图应用的C++设计优化方案
核心思路
- 用C++模板+类型擦除替代
std::any的手动类型转换,兼顾类型安全与代码简洁性 - 为每个Block明确绑定输入输出类型,避免运行时类型查找的冗余操作
- 保留Block的扩展性,支持任意输入输出类型组合,同时适配无状态/有状态的不同场景
推荐设计模式:类型擦除+模板策略
1. 抽象Block基类(类型擦除)
定义统一的对外接口,屏蔽具体类型细节,所有功能Block都继承自该基类。
2. 模板化的具体Block(策略模式)
通过模板指定输入输出类型,实现强类型的处理逻辑,彻底消除手动any_cast的繁琐与风险。
优化后代码示例
基础框架实现
#include <vector> #include <unordered_set> #include <iostream> #include <memory> #include <any> // 抽象Block基类:统一对外接口 class Block { public: virtual ~Block() = default; virtual std::any process(std::any in) = 0; }; // 无状态模板Block:适用于纯函数式的处理逻辑 template<typename InputT, typename OutputT> class StatelessTypedBlock : public Block { public: using Processor = OutputT(*)(const InputT&); explicit StatelessTypedBlock(Processor proc) : processor(proc) {} std::any process(std::any in) override { return processor(std::any_cast<const InputT&>(in)); } private: Processor processor; }; // 有状态模板Block:适用于需要保存配置/状态的场景 template<typename InputT, typename OutputT> class StatefulTypedBlock : public Block { public: virtual OutputT process(const InputT& in) = 0; std::any process(std::any in) override { return process(std::any_cast<const InputT&>(in)); } };
具体功能Block实现
// 乘法运算Block:输入vector<float>,输出float class MultiplyBlock : public StatefulTypedBlock<std::vector<float>, float> { public: float process(const std::vector<float>& in) override { float product = 1.0f; for (float f : in) { product *= f; } return product; } }; // 数据解析Block:输入unordered_set<std::byte>,输出bool class InterpretDataBlock : public StatefulTypedBlock<std::unordered_set<std::byte>, bool> { public: explicit InterpretDataBlock(std::byte magic_byte) : magic_byte(magic_byte) {} bool process(const std::unordered_set<std::byte>& in) override { return in.contains(magic_byte); } private: std::byte magic_byte; };
主函数测试
int main() { // 无状态Block示例:实现平方运算 auto square_block = std::make_unique<StatelessTypedBlock<float, float>>( [](const float& in) { return in * in; } ); std::cout << std::any_cast<float>(square_block->process(3.0f)) << std::endl; // 有状态Block测试 MultiplyBlock multiply_block; std::cout << std::any_cast<float>(multiply_block.process(std::vector<float>{1, 2, 3})) << std::endl; InterpretDataBlock interpret_block(std::byte{'Q'}); std::unordered_set<std::byte> data{std::byte{0}, std::byte{1}, std::byte{'Q'}}; std::cout << std::boolalpha << std::any_cast<bool>(interpret_block.process(data)) << std::endl; return 0; }
优化亮点
- 类型安全:编译期即可检查输入输出类型匹配,避免运行时
any_cast失败的风险 - 代码简洁:无需手动维护类型映射表,子类只需实现强类型的
process方法 - 扩展性强:支持无状态(函数式)和有状态的Block,新增类型只需实现对应模板子类
- 性能提升:减少运行时类型查找和转换的额外开销
内容的提问来源于stack exchange,提问作者user23952
相关产品推荐
相关产品推荐

