为什么必须转发声明一个类并在头文件中包含相应的头文件 [英] Why must we Forward Declare a class and include the corresponding header file in a header file

查看:147
本文介绍了为什么必须转发声明一个类并在头文件中包含相应的头文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我注意到,如果我包括一个头文件在 .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 的成员。 : - )

However if you provide forward declaration of A in the header B.h, then you have to include the header file A.h in the implementation file of B which is B.cpp, because in the implementation file of B, you need to access the members of A for which the compiler requires the complete definition of A. Well again, include only if you need to access the members of A. :-)


对不起,我没有看到你答案的最后一段。令人困惑的是,为什么我也需要前向声明。不包括头文件A.h单独提供类A的完整定义? -

Sorry I didn't see the last paragraph of your answer. What is confusing me is why do I need the forward declaration also. Doesn't including the header file A.h alone provides complete definition of class A?? –

我不知道头文件中有什么。此外,如果尽管包括头文件,您还需要提供前向声明,然后它暗示头实现不正确。我怀疑有循环依赖

I don't know what is there in the header file. Also, if in spite of including the header file, you also need to provide the forward declaration, then it implies that the header is implemented incorrectly. I suspect that there is a circular dependency:


  • 确保没有两个头文件其他。例如,如果 Ah 包括 Bh ,则 Bh 不包括直接或间接的 Ah

  • Make sure that no two header files include each other. For example, if A.h includes B.h, then B.h must not include A.h, directly or indirectly.

使用向前声明和指针声明来打破这种循环依赖。逻辑非常简单。如果您不能在 Bh 中包含 Ah ,这意味着您不能声明 A a Bh (因为这样,你必须包括头 Ah )。因此,即使您不能声明 A a ,仍然可以声明 A * pA ,为此, A 就够了。

Use forward declaration and pointer-declaration to break such circular dependency. The logic is pretty much straight-forward. If you cannot include A.h in B.h, which implies you cannot declare A a in B.h (because for this, you have to include the header A.h also). So even though you cannot declare A a, you can still declare A *pA, and for this a forward declaration of A is enough. That way you break the circular dependency.

希望有帮助。

这篇关于为什么必须转发声明一个类并在头文件中包含相应的头文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆