Tah*_*lil 4 c++ class header-files forward-declaration
嗨,我注意到如果我在头文件中包含头文件,.cpp那么我可以创建该头文件类的对象.就像如果我有A.h在main.cpp那我可以写A *a;的main.cpp.但是,如果我在另一个头文件中包含头文件,然后尝试创建包含头文件的对象,则这不起作用.喜欢,
档案B.h:
#include "A.h"
class B
{
public:
B(){};
A *a;
};
Run Code Online (Sandbox Code Playgroud)
我必须添加类的前向声明A才能使它工作.为什么?
Naw*_*waz 14
以下是基础知识:
对于任何类型的A,如果声明类型的变量A&,A*,A**,A***,等,则编译器不需要知道的完整定义A的变量声明的网站.所有它需要知道这A是一种类型; 这就对了.所以前瞻声明就足够了:
class A; //forward declaration
class B
{
A * pA; //okay - compiler knows A is a type
A & refA;/ okay - compiler knows A is a type
};
Run Code Online (Sandbox Code Playgroud)
完整的定义并不 需要,因为编译器仍然可以计算sizeof(B)而这又取决于sizeof(A*)与sizeof(A&)这些被称为编译器,即使它不知道- sizeof(A).注意,这sizeof(A*)只是该平台上指针的大小(通常 4是32位系统上的8字节或64位系统上的字节).
对于任何类型的A,如果声明类型的变量A,A[N],A[M]N]等等,那么编译器需要知道类型的完整定义A的变量声明的网站.远期声明将不会有足够的在这种情况下.
class A; //forward declaration
class B
{
A a; //error - the compiler only knows A is a type
//it doesn't know its size!
};
Run Code Online (Sandbox Code Playgroud)
但这是正确的:
#include "A.h" //which defines A
class B
{
A a; //okay
};
Run Code Online (Sandbox Code Playgroud)
完整的定义是 必需的,以便编译器可以计算sizeof(A),如果编译器不知道定义,则这是不可能的A.
请注意,类的定义意味着"类成员的完整规范,类型以及类是否具有虚函数".如果编译器知道这些,它可以计算类的大小.
了解这些基础知识后,您可以决定是否将标题包含在其他标题中,或者只有前向声明就足够了.如果前向声明足够,那么您应该选择该选项.包括头只有在它需要.
不过,如果你提供向前的声明A在标题B.h,那么你必须包含头文件A.h的实现文件的B是B.cpp,由于在执行文件B,你需要访问成员A为其编译器要求的完整定义A.好了,只有当你需要访问成员时才包含A.:-)
对不起,我没有看到你答案的最后一段.令我困惑的是为什么我也需要前瞻性声明.不包括头文件啊单独提供A类的完整定义? -
我不知道头文件中有什么.此外,如果尽管包含头文件,您还需要提供前向声明,那么它意味着标头实现不正确.我怀疑存在循环依赖:
确保没有两个头文件相互包含.例如,如果A.h包含B.h,则B.h不得A.h直接或间接包含.
使用前向声明和指针声明来打破这种循环依赖.逻辑非常简单.如果您不能包括A.h在B.h,这意味着你不能声明A a在B.h(因为这一点,你必须包括头A.h也).所以即使你不能声明A a,你仍然可以声明A *pA,为此,前向声明A就足够了.这样你就打破了循环依赖.
希望有所帮助.