C++前置声明和#include
https://www.zhihu.com/question/63201378
前置声明用处:
1.前置声明能够节省编译时间
2.在两个类相互引用时用前置声明
当然应当尽量避免这样设计,需要依赖倒置规避
3.前置声明,在写wrapper的时候,会发现是屏蔽内部宏定义的好方法
比如,需要写一个动态库,并提供头文件给别人使用,头文件是这样的
class ImgAnalysis;
DLL_EXPORT ImgAnalysis* create_img_analysis(const ImgAnalysisCfg *cfg);
DLL_EXPORT int run_img_analysis(ImgAnalysis* img_analysis, ImgAnalysisInput* input);
DLL_EXPORT void destory_img_analysis(ImgAnalysis* img_analysis);
ImgAnalysis这个类里面有很多成员变量,依赖其它很多头文件,如果不前置声明,就要放在这个头文件中,那别人使用这个头文件,就要把ImgAnalysis这个类需要的头文件全包含进来,有前置声明,这个头文件才能如此干净,使用的人也方便很多。如果没有前置声明,还有一种方法就是void指针,然后强制类型转换,不过我是极度讨厌void的,void*一眼看不出类型, 能不用就不用。
前置声明的劣势
例如,如果一个类的实现者需要把这个类改个名字/换个命名空间,出于兼容性他原本可以在原命名空间里/用原名通过using来起一个别名指向新类。然而别名不能被前向声明。内网有一份代码改动一下子试图修改总计265个头文件,就是实现者为了要改这个类的名字而不得不去改所有的调用处。想一想,如果这265个文件分属于50个不同的团队,你得拿到50个人的同意才能提交这份改动,想不想打人?
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)
若把#include换成前置声明,由于声明时不知道D是B的子类,test()中f(x)就会导致f(void)被调用,而不是f(B)。
等等
结论:
还是用#include比较稳妥,写库的时候可能会用到前置声明