C++依赖注入场景下不同源文件同名类为何指向同一实例?
问题根因
你遇到的是C++**单一定义规则(One Definition Rule, ODR)**冲突:
两个翻译单元(do_a.cpp、do_b.cpp)的全局命名空间下都定义了同名的Do类,这类属于外部链接属性,链接器处理重复符号时会默认合并,仅保留第一个找到的Do类的相关实现(包括虚函数表),所以两次print调用都会执行第一个加载的Do类的实现,输出两次ImplA。
解决方案
1. 最推荐:使用匿名命名空间限制可见性
你自己找到的将Do类放入匿名命名空间的方案就是C++标准规定的、用于将符号可见性限制在当前翻译单元的标准解法:
匿名命名空间内的所有类型、函数、变量都默认是内部链接属性,仅对当前cpp文件可见,不同翻译单元的匿名命名空间内的同名符号完全独立,不会发生符号冲突。你提供的已经加了匿名命名空间的代码可以直接运行,输出结果完全符合预期。
2. 其他可行方案
如果不想用匿名命名空间,也可以用以下方式解决,同样不需要修改Do类名:
- 为每个cpp里的
Do类套上独立的自定义命名空间,比如namespace impl_a、namespace impl_b - 将两个实现类所在的cpp分别编译为独立的动态库,运行时动态加载,也可以避免符号冲突,但实现复杂度远高于匿名命名空间,仅适用于特定的插件化场景。
内容的提问来源于stack exchange,提问作者Steven Green
相关产品推荐
相关产品推荐

