💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
最近被自己坑儿了一把,改别人的代码,最后编译器这样报错的: **error C2653: not a class or namespace name** 简单描述一下: 有一个类A,声明和实现分别位于 a.h和a.cc中 有一个类B,声明和实现分别位于 b.h和b.cc中 类A的某个成员函数需要B类类型作为参数 类B的某个成员函数需要A类类型作为参数 a.h文件如下: ~~~ #ifndef A_H_ #define A_H_ #include "b.h" class A { public: enum State { RIGHT = 0; ERROR = 1; } void send (B b); ... }; #endif ~~~ a.cc文件省略,无影响 b.h文件是这样的: ~~~ #ifndef B_H_ #define B_H_ #include "a.h" class B { public: void send (A::State state); ... }; ~~~ 此时呢,编译器就会报错: error C2653: A not a class or namespace name 这时候我们的第一反应往往是查看b.h中是否包含了A类所在的头文件,即是否包含了a.h文件。 但是坑爹的是,我们明明包含了呀,怎么还会报错呢? 好吧,就是相互包含的事儿,编译器已经蒙掉了。 简而言之就是不要包含不必要的头文件。 偶对了 差点忘告诉怎么修改了? 首先,我们是把类A和B放在了一个命名空间中,即对A和B都进行了 namespace KENG{ }封装。 所以这个时候,我们可以在A中不包含B的头文件,而改成前置声明、、、、、 ~~~ #ifndef A_H_ #define A_H_ class B; class A { public: enum State { RIGHT = 0; ERROR = 1; } void send (B b); ... }; #endif ~~~ 大功告成! 我们用#ifndef躲过了重复包含头文件的坑儿,但是我们也不能肆无忌惮的包含,更要避免相互包含的情况!!!