问题描述
您好,我注意到,如果我包括一个头文件在 .cpp 然后我可以创建一个头文件的类的对象。如果我在中包含 Ah ,那么我可以写 A * a; 在 main.cpp 。但是这不工作,如果我包括头文件在另一个头文件,然后尝试创建包括头文件的对象。喜欢,
Hi I noticed if I include a header file in a .cpp then I can create an object of that header file's class. Like if I includeA.h in main.cpp then I can write A *a; in main.cpp. But this doesn't work if I include a header file in another header file and then try to create the object of that included header file. Like,
档案 Bh :
file B.h:
#include "A.h" class B { public: B(){}; A *a; };
我必须添加类 A 使其工作。为什么?
I have to add forward declaration of the class A to make it work. Why?
推荐答案
以下是基本信息:
-
对于任何类型 A ,如果您声明一个类型 A& 的变量, c $ c> A * , A ** , A *** 等,则编译器在变量声明的站点不需要知道的完整定义 A 。所有它需要知道 A 是一个类型;这就对了。所以一个向前的声明就足够了:
For any type A, if you declare a variable of type A&, A*, A**, A***,etc, then the compiler does not need to know the complete definition of A at the site of variable declaration. All it needs to know that A is a type; that is it. So a forward declaration is enough:
class A; //forward declaration class B { A * pA; //okay - compiler knows A is a type A & refA;/ okay - compiler knows A is a type };
完整的定义是不 required ,因为编译器仍然可以计算 sizeof(B),它依次取决于 sizeof(A *)和 sizeof(A&)—这些是编译器已知的,即使它不知道 sizeof(A)。注意, sizeof(A *)只是该平台上的指针大小(通常 4 字节或64位系统上的 8 字节)。
The complete definition is not required because the compiler can still compute sizeof(B) which in turn depends on sizeof(A*) and sizeof(A&) — these are known to the compiler, even though it doesn't know sizeof(A). Note that sizeof(A*) is just a size of pointer on that platform (which is usually 4 bytes on 32bit system or 8 bytes on 64bit system).
,,如果您声明一个类型 A , A [N] , A [M] N] 等等,那么编译器需要知道类型 A 在变量声明的站点。
For any type A, if you declare a variable of type A, A[N], A[M]N] etc, then the compiler needs to know the complete definition of type A at the site of variable declaration. A forward declaration would not be enough in this case.
class A; //forward declaration class B { A a; //error - the compiler only knows A is a type //it doesn't know its size! };
但这是正确的:
#include "A.h" //which defines A class B { A a; //okay };
完整定义是 必需编译器可以计算 sizeof(A),如果编译器不知道 A 的定义,这是不可能的。
The complete definition is required so that the compiler could compute sizeof(A), which is not possible if the compiler doesn't know definition of A.
请注意,类的定义意指类成员的完整规范,它们的类型,以及类是否具有虚函数) 或不。如果编译器知道这些,它可以计算类的大小。
Note that definition of a class means "the complete specification of the class members, their types, and whether the class has virtual function(s) or not". If the compiler knows these, it can compute the size of the class.
了解这些基本知识后,您可以决定是否将标头包含在其他标头中,如果前向声明是足够的,那就是你应该选择的选项。
Knowing these basics, you can decide whether to include headers to other headers or only forward declaration would be enough. If the forward declaration is enough, that is the option you should choose. Include a header only if it is required.
但是,如果您提供 中的 因为在 B的实现文件中, B 的实现文件是 B.cpp ,您需要访问 A 的成员,因为编译器需要完整定义 A 。再次,请只有 需要访问 A 的成员。 : - )
我不知道头文件中有什么。此外,如果尽管包括头文件,您还需要提供前向声明,然后它暗示头实现不正确。我怀疑有循环依赖:
这篇关于为什么必须转发声明一个类并在头文件中包含相应的头文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!