c – 为什么我们必须转发声明一个类并在头文件中包含相应的头文
嗨,我注意到如果我在.cpp中包含一个头文件,那么我可以创建该头文件类的对象.就像我在main.cpp中包含了a.h,然后我可以写A * a;在main.cpp中.但是,如果我在另一个头文件中包含头文件,然后尝试创建包含头文件的对象,则这不起作用.喜欢,
文件B.h: #include "A.h" class B { public: B(){}; A *a; }; 我必须添加A类的前向声明才能使它工作.为什么? 解决方法
以下是基础知识:
>对于任何类型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 }; 完整的定义不是必需的,因为编译器仍然可以计算sizeof(B),而sizeof(B)又取决于sizeof(A *)和sizeof(A&) – 这些都是编译器已知的,即使它不知道sizeof(A) ).请注意,sizeof(A *)只是该平台上指针的大小(通常在32位系统上为4个字节,在64位系统上为8个字节). 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的定义,这是不可能的. 请注意,类的定义意味着“类成员的完整规范,类型以及类是否具有虚函数”.如果编译器知道这些,它可以计算类的大小. 了解这些基础知识后,您可以决定是否将标题包含在其他标题中,或者只有前向声明就足够了.如果前向声明足够,那么您应该选择该选项.仅在需要时包括标头. 但是如果你在标题Bh中提供A的前向声明,那么你必须在B的实现文件中包含头文件Ah,即B.cpp,因为在B的实现文件中,你需要访问A的成员编译器需要A的完整定义.再次,仅当您需要访问A的成员时才包括:.-)
我不知道头文件中有什么.此外,如果尽管包含头文件,您还需要提供前向声明,那么它意味着标头实现不正确.我怀疑存在循环依赖: >确保没有两个头文件相互包含.例如,如果A.h包括B.h,则B.h不得直接或间接包括A.h. 希望有所帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |