C++中‘Member access into incomplete type’错误的成因及解决思路咨询
为什么会出现"Member access into incomplete type 'B'"错误?怎么解决?
首先咱们拆解下这个错误的核心成因:
当编译器编译struct A里的funcA函数体时,它只看到了struct B的前向声明(struct B;),这时候B属于不完全类型——编译器只知道B是个结构体,但完全不清楚它的成员(包括funcB这个成员函数)的具体信息。所以你在funcA里写b.funcB(*this)的时候,编译器根本找不到B::funcB的定义,自然就抛出错误了。
你的思路方向完全是对的!交换位置后错误变化,本质就是编译器处理代码的顺序问题:如果先定义B再定义A,编译A::funcA时B已经是完整类型了,但这时候B里有A a;,而A还没完整定义,又会出现新的问题(因为B里需要A的完整类型来创建成员对象)。
那怎么解决这个循环依赖的问题?给你两种常用的靠谱方案:
方案1:把成员函数实现移到结构体定义之后
把A::funcA的函数体从结构体内部移出来,放到B的完整定义之后,这样编译器处理funcA的时候,B已经是完整类型,能顺利找到funcB:
struct B; struct A { void funcA(B &b); // 只声明,不写函数体 }; struct B { A a; void funcB(A a1) { } }; // 现在B已经是完整类型了,可以安全实现A::funcA void A::funcA(B &b) { b.funcB(*this); // 不再报错 }
方案2:用分离编译(头文件+源文件)规范处理
如果代码量较大,更推荐这种工程化的做法,把结构体声明和实现分开:
a.h:
#pragma once struct B; struct A { void funcA(B &b); };
b.h:
#pragma once #include "a.h" struct B { A a; void funcB(A a1); };
a.cpp:
#include "a.h" #include "b.h" void A::funcA(B &b) { b.funcB(*this); }
b.cpp:
#include "b.h" void B::funcB(A a1) { // 这里写你的函数逻辑 }
这样不管编译哪个文件,都能获取到对应类型的完整定义,完美解决循环依赖的问题。
内容的提问来源于stack exchange,提问作者rvedtsaneon
相关产品推荐
相关产品推荐

