我想知道在可能的情况下在所有地方使用前向声明是否有任何缺点。这是我的标题只包含声明。
据我所知,使用前向声明可加快编译时间,但我不知道有什么缺点。
啊:
Class A
{
};
b.h:
// Should I use and include "a.h" in the cpp file (e.g., a.cpp)
Class A;
Class B
{
doSomething(A *a);
A *myA;
};
或者它是否更好用
b.h:
#include "a.h"
Class B
{
doSomething(A *a);
A *myA;
};
使用前向声明可以改善解耦。如果你可以通过使用前向声明来避免包括"A.h"
,那么使用前向声明是个好主意。最好不仅因为你的构建运行得更快(毕竟,预处理的头文件可以很好地处理编译器的效率),但是因为它告诉读者你的声明你的类B
的结构不依赖于你对类的了解A
除了存在之外*。
编辑(回答你的问题)我知道转发声明的唯一缺点是你不能在所有情况下使用它们:例如,类似于这样的声明:
class B
{
A myA[10];
};
不会编译,因为编译器需要知道A
的大小。但是,编译器可以非常可靠地发现这些问题,并以明确的方式通知您。
*类B
的实现很可能取决于知道类A
的细节。但是,这种依赖关系变成了隐藏在你班级用户身上的B
的实现细节;您可以随时更改它,而不会破坏依赖于类B
的代码。
使用前向声明可加快编译时间
这是部分正确的,因为编译器(和预处理器)不需要在包含此标头的每个文件中解析包含的标头。
更改标题并需要重新编译时看到的真正改进。
前向声明是打破循环包含的唯一方法。
我会用实际的话说。优点:
缺点:
前向声明是打破循环包含的唯一方法。
我认为,如果不小心使用,这是主要的缺点。我在一个大型项目中工作,尽可能做出前瞻性声明。循环依赖最终是一个真正的问题。
想到的唯一缺点是前向声明需要指针。因此,它们可能未初始化,因此可能导致空引用异常。作为我目前使用的编码标准,要求所有指针都需要空引用检查是否可以添加分配代码。我开始用Design By Contract不变量来解决这个问题;然后我可以断言在构造函数中初始化的任何东西都不会为null。