1

我被告知不要在 .header 中包含太多类,如果我可以避免的话,而是将它们包含在 .cpp 中。为此,他们告诉我创建原型类,例如:

class abc;

代替:

include "abc.h"

但这只是为了以防 abc 类没有被用作属性或返回值。如果是参数,我可以使用原型……这是为什么呢?

另外,为什么在 .h 文件中包含如此多的标头如此糟糕?

谢谢

4

5 回答 5

2

当您前向声明一个类时:

class abc;

is 变成了不完整的类型,你只能用不完整的类型做某些事情。例如,任何需要知道类成员的知识,甚至需要知道它的大小的东西,都需要一个完整的声明。

至于包含来自其他标头的标头,我可以想到两个反对的论点:

  1. 改进的构建时间。
  2. 更少的依赖。

第一个可能相关,也可能不相关,具体取决于项目的大小、编译器、硬件等。第二个也有问题,因为它并没有真正减少类之间的依赖关系。

必须使用前向声明的一种情况是,在不同标头中定义的两个类之间存在循环依赖关系。

于 2013-03-21T11:29:48.323 回答
2

如果是参数,我可以使用原型……这是为什么呢?

只要您不需要访问已声明类的内部结构,就可以使用前向声明,例如,当您声明指针、引用或将其作为参数传递时。你不能使用前向声明来继承一个类,调用它的任何成员函数或访问它的成员,或者声明非指针/引用类型的成员:这是因为编译器必须知道类的内部结构才能执行上述任何操作。

为什么在 .h 文件中包含如此多的标头如此糟糕?

这本身并不是普遍“坏”的,但是对于许多编译器,它可能会减慢编译过程,因此通常会尽量减少包含内容。现代编译器具有有用的功能(例如预编译的头文件)来最大限度地减少影响,因此在您可以使用前向声明的地方变得更像是一种审美选择而不是实际问题。

于 2013-03-21T11:31:22.360 回答
1
class abc;

当您转发声明一个类型时,编译器会将其视为Incomeplete 类型,并且它没有任何关于该类型的内存布局/组成的信息。所以你不能要求编译器执行任何需要它知道这些信息的操作。

使用不完整类型,您不能:

  • 用它来声明一个成员。
  • 使用此类型定义函数或方法。

但是使用不完整类型,您可以:

  • 将成员声明为指向不完整类型的指针。
  • 声明接受/返回不完整类型的函数或方法。
  • 定义接受/返回指向不完整类型的指针的函数或方法(但不使用其成员)。

为什么在 .h 文件中包含如此多的标头如此糟糕?

这很糟糕,因为:

  • 包含标题只是将标题的内容复制粘贴到当前翻译单元。这会增加编译时间并构建依赖项。
于 2013-03-21T11:30:13.243 回答
0

包含许多标题是不好的,因为如果您更改其中一个,您还必须编译您的文件,这听起来可能不是问题,但对于大型程序,编译+链接可能需要很多时间(有时是几个小时)

于 2013-03-21T11:31:05.310 回答
0

编译器需要知道的只是名称——而不是组合——直到它需要生成代码。

所以前向声明是要走的路——因为它不需要加载和解析。

顺便说一句 - makefile 不必开始重新编译东西会有所帮助。

于 2013-03-21T11:41:01.430 回答