C++头文件循环引用导致所需数据类型无法访问的问题如何解决?
问题本质
这是典型的C++头文件循环依赖问题:TriangleProcessor类因为持有Renderer的值类型成员,必须在头文件中引入renderer.h;而Renderer需要用到TriangleProcessor内部定义的vtris别名,又需要引入triangleProcessor.h,二者互相依赖对方的完整定义,哪怕加了#pragma once也无法解决展开顺序的冲突。
最优解决方案:抽离公共类型定义
把两个类都要用到的公共类型从业务类中剥离,放到独立的公共头文件,从根源打破循环依赖,这也是耦合度最低的方案,修改步骤如下:
1. 修改triangle.h,把公共别名移到公共头
原本绑定在TriangleProcessor内部的vtris别名不属于业务逻辑的私有定义,属于和Triangle强相关的公共类型,直接放到triangle.h中即可:
#pragma once #include <vector> class Triangle{}; // 公共别名移到此处,所有用到的文件直接引入triangle.h即可 using vtris = std::vector<Triangle>;
2. 修改triangleProcessor.h,删掉重复的内部别名
#pragma once #include <vector> #include "triangle.h" #include "renderer.h" class TriangleProcessor { public: TriangleProcessor() = default; private: Renderer renderer; public: // 直接使用公共头中定义的vtris即可 std::vector<vtris> vvTris; private: void Render() { renderer.RenderTriangles(vvTris); } };
3. 修改renderer.h,只引入公共头即可,无需依赖triangleProcessor.h
#pragma once #include <vector> #include "triangle.h" class Renderer { // 此处可以正常识别vtris类型 void RenderTriangles(const std::vector<vtris>& vvtris) { //渲染所有三角形 } };
可选方案:保留别名的类内定义
如果你一定要把vtris作为TriangleProcessor的内部别名,可以调整依赖形式,把TriangleProcessor中的Renderer成员改为指针/引用类型,配合前置声明打破循环:
- 在
triangleProcessor.h中前置声明Renderer类,删掉#include "renderer.h",把Renderer renderer改为Renderer* renderer或者std::unique_ptr<Renderer> renderer - 在
triangleProcessor.cpp中引入renderer.h,实现Render方法和构造函数中初始化Renderer指针 - 在
renderer.h中直接引入triangleProcessor.h,即可正常使用TriangleProcessor::vtris类型
内容的提问来源于stack exchange,提问作者user16038533
相关产品推荐
相关产品推荐

