c ++头文件相互包含在一起

Meg*_*anX 41 c++ header include

我有两个类都在单独的头文件中定义.每个文件都有一个其他类的字段.现在我在每个文件的头文件中包含了其他文件的头文件,但是编译器正在生成错误.我错过了什么?

Mik*_*kis 54

你不能让每个班级都有"其他类型的领域"; 这将是一个递归定义,不仅编译器无法理解它,它甚至没有逻辑意义.

每个具有另一个类型的字段的类是您在MC Escher图纸或其动画中看不到的那种不可能性,如下所示:

 

                                            基于埃舍尔的

                                           资料来源:escherdroste.math.leidenuniv.nl

                       基于埃舍尔的"印刷画廊"石版画,1956年,见维基百科

 

两个字段中的一个必须是一个指针,以便打破递归包含,并避免逻辑上的不可能性.

这带来了下一个问题:如果B类要包含A类的实例,那么很明显,A必须在B类之前声明,因此在编译B时编译器已经知道A.但是如果A类是在B类之前声明,我们怎样才能在A中声明一个指向B的指针?在编译A时,B类还不知道!对此的答案是一种称为前向声明的特殊结构,其精确存在以适应这种情况.B类的前向声明如下:

class B;
Run Code Online (Sandbox Code Playgroud)

所有它告诉编译器将会有一个名为B的类.它没有告诉编译器有关B类内容的任何信息,所以我们可以用它做很少的事情,但是我们可以做一件事:声明指针到B.

因此,问题的完整解决方案如下所示:

档案"啊":

/* This is called a "forward declaration".  We use it to tell the compiler that the 
   identifier "B" will from now on stand for a class, and this class will be defined 
   later.  We will not be able to make any use of "B" before it has been defined, but 
   we will at least be able to declare pointers to it. */
class B;

class A
{
    /* We cannot have a field of type "B" here, because it has not been defined yet. 
       However, with the forward declaration we have told the compiler that "B" is a 
       class, so we can at least have a field which is a pointer to "B". */
    B* pb; 
}
Run Code Online (Sandbox Code Playgroud)

档案"Bh":

#include "A.h"

class B
{
   /* the compiler now knows the size of "A", so we can have a field of type "A". */
   A a;
}
Run Code Online (Sandbox Code Playgroud)

  • [动画来源](http://escherdroste.math.leidenuniv.nl/index.php?menu=animation) (2认同)

Mat*_*cey 21

您不应该将头文件包含在其他文件中,只需在源文件中包含头文件即可.

在标题中,您可以使用前向声明:

// In Class1.h
class Class2;

// In class2.h
class Class1;
Run Code Online (Sandbox Code Playgroud)

您还可以使用预处理器防止文件被包含两次:

// Class1.h
#ifndef __CLASS_1_H
#define __CLASS_1_H

// content

#endif
Run Code Online (Sandbox Code Playgroud)

  • 注意:前向声明意味着您只能将该类用作头文件中的指针.不是类实例. (7认同)
  • 您还可以将其用作函数声明中的返回类型或参数类型以及引用类型的一部分。 (2认同)

Boy*_*nux 14

我知道这是一个古老的话题,但也许你仍然对解决方案感兴趣!

实际上在C++中,你可以在不使用指针的情况下递归使用两个类,这里​​是如何做到的.

档案:啊

#include <b.h>

class A {
    B<> b;
}
Run Code Online (Sandbox Code Playgroud)

档案:bh

class A;

template<typename T = A>
class B {
    T a;
}
Run Code Online (Sandbox Code Playgroud)

file:main.cpp

#include "a.h"    
A a;
Run Code Online (Sandbox Code Playgroud)

就这样!

当然这只是为了好奇:)

  • 我会给你+1这个:-) (2认同)
  • 你试过编译吗?MSVC 给了我错误:`"B&lt;A&gt;::a" uses an undefined class "A"` (2认同)