定义
A "forward declaration" is a declaration of an entity without an associated definition.
“前向声明”是没有关联定义的实体声明。
前置声明的作用
避免重复定义变量
避免引入函数定义/声明文件,从而函数文件发生更改时不会重新编译依赖文件
解决循环依赖问题
优点
节约编译时间,前置声明了一个类,那么只会编译这个类,而不会编译与之同属一个文件的其它代码。
处理两个类互相依赖的问题,两个类互相包含
// A.h #include "B.h" class A { B b; }; // B.h #include "A.h" class B { A a; };
缺点
前置声明隐藏了依赖关系,头文件改动时,用户的代码会跳过必要的重新编译过程。
前置声明可能会被库的后续更改所破坏。前置声明函数或模板有时会妨碍头文件开发者变动其API。比如想改类的名称,在大型项目中,可以采用兼容做法,将旧类名作为新类名的别名,但是别名不能作为前置声明,所以需要修改类名则需要修改所有前置声明了该类的地方,可能来自多个部门的开发人员用过,这就不太好处理了。
前置声明来自 std:: 的 symbol 时,其行为未定义。
前置声明的类因为只能使用指针或引用,当删除一个前置声明的类的指针时,此行为是未定义的。
很难判断什么时候该用前置声明,什么时候该用 #include。极端情况下,用前置声明代替 #include 可能会悄悄地改变代码的含义:
// 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*)。
建议
尽可能避免使用前向声明。相反,请包含所需的头文件。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !