C++代码设计:不使用类如何隐藏工具包内非公开工具函数
实现方案
以下方案均满足MISRA C++编码规范要求,不会触发多继承相关的合规问题。
不使用类的实现方案
核心思路是给内部函数a、b设置内部链接属性,让这两个函数的符号仅在当前cpp编译单元内可见,外部编译单元既无法拿到函数声明,也无法链接到对应实现,从编译和链接两个层面阻止外部调用。
- 匿名命名空间实现(C++标准推荐写法)
对外发布的头文件中仅声明需要暴露的函数c,在cpp实现文件中用匿名命名空间包裹内部函数a、b即可。
头文件my_tool.h示例:
实现文件#ifndef MY_TOOL_H #define MY_TOOL_H namespace myName { void c(/* 对应参数列表 */); } #endifmy_tool.cpp示例:
这种写法完全保留你原有函数的实现逻辑,不需要做业务改动,#include "my_tool.h" namespace myName { // 匿名命名空间内的所有内容仅当前编译单元可访问 namespace { void a(/* 对应参数列表 */) { // 原有业务逻辑 } void b(/* 对应参数列表 */) { // 原有业务逻辑 } } void c(/* 对应参数列表 */) { a(/* 传参 */); b(/* 传参 */); } }a、b可以正常调用两个业务类的接口,不存在耦合问题。 - static文件级函数实现(兼容C风格写法)
直接在cpp文件中给a、b的定义加上static修饰符,效果和匿名命名空间完全一致,两个函数仅在当前cpp文件内可见。这种写法MISRA C同样允许,只是匿名命名空间对类型、常量等其他内部元素的隐藏支持更统一,是C项目的首选。
合规类重构路径
如果团队规范偏向类封装,不需要使用多继承,直接实现无继承关系的纯静态工具类即可,完全规避MISRA对多继承的限制:
头文件示例:
#ifndef MY_TOOL_H #define MY_TOOL_H namespace myName { class CrossClassUtil final { public: // 禁用构造/析构,明确类为纯静态工具集合,不允许实例化 CrossClassUtil() = delete; ~CrossClassUtil() = delete; // 仅对外暴露c接口 static void c(/* 对应参数列表 */); private: // a、b为私有静态成员,仅类内部可访问 static void a(/* 对应参数列表 */); static void b(/* 对应参数列表 */); }; } #endif
实现文件中正常编写三个静态成员函数的逻辑即可,外部调用时直接使用myName::CrossClassUtil::c(/*传参*/)。这种实现下a、b是类私有成员,外部没有访问权限,类本身不继承任何其他基类,不存在多继承违反MISRA规范的问题,也不会和你原本跨两个类的业务逻辑产生冲突。
注意:不要尝试用友元、嵌套类等复杂结构实现隐藏,上述两种方案已经是实现成本最低、合规性最高的方式,额外增加复杂结构反而容易触发MISRA其他规则告警。
内容的提问来源于stack exchange,提问作者David Boshton
相关产品推荐
相关产品推荐

