c++头文件相互包含

2022-01-11 00:00:00 header include c++

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

I have two classes both defined in separate header files. Each file has a field that is type of other class. Now I included in header of each file the header of other file, but compiler is generating errors. What am i missing?

推荐答案

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

You cannot have each class have "a field that is type of other class"; that would be a recursive definition and not only the compiler would not be able to make any sense out of it, it does not even make logical sense.

每个类都有一个字段是另一个类的类型,这是你只能在 M.C. 中看到的那种不可能.埃舍尔的画作,或其动画,像这样的:

Each class having a field that is type of the other class is the kind of impossibility that you only see in M.C. Escher drawings, or animations thereof, like this one:

 

                      

                                           

         B.de Smit 和 HW Lenstra - 来源:escherdroste.math.leidenuniv.nl

                 B. de Smit and H. W. Lenstra - Source: escherdroste.math.leidenuniv.nl

           基于 Escher 的印刷画廊"平版印刷,1956,参见维基百科

                     based on Escher's "Print Gallery" Lithograph, 1956, see Wikipedia

 

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

One of the two fields will have to be a pointer, so as to break the recursive containment, and avoid the logical impossibility.

这就引出了下一个问题:如果类 B 包含类 A 的一个实例,那么显然 A 必须在类 B 之前声明,这样编译 B 时编译器就已经知道了 A.但是如果A类在B类之前声明,我们如何在A中声明一个指向B的指针?在编译 A 时,B 类还不知道!对此的答案是一种称为前向声明的特殊结构,它的存在正是为了适应这种情况.B 类的前向声明如下所示:

Which brings us to the next problem: if class B is to contain an instance of class A, then obviously, A has to be declared before class B, so that A is already known to the compiler when compiling B. But if class A is declared before class B, how can we declare a pointer to B in A? Class B is not known yet at the time that A is compiled! The answer to this is a special construct known as forward declaration which exists precisely in order to accommodate situations like this. A forward declaration of class B looks like this:

class B;

它只是告诉编译器会有一个名为 B 的类.它不会告诉编译器关于 B 类的任何内容,所以我们几乎无能为力,但我们可以做一件事: 声明指向 B 的指针.

All it is telling the compiler is that there will be a class called B. It does not tell the compiler anything about the contents of class B, so there is very little we can do with it, but we can do one thing: declare pointers to B.

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

So, the full solution to the problem looks like this:

文件A.h":

/* 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 yet been
       defined. 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; 
}

文件B.h":

#include "A.h"

class B
{
   /* the compiler now knows the size of "A", so we can have a field
      of type "A". */
   A a;
}

相关文章