C++ 远期申报的目的是什么?

C++ 远期申报的目的是什么?,c++,declaration,C++,Declaration,以下内容的描述或含义是什么: 例如: class test; class test { ..... }; 首先声明类,然后定义它 声明:它只是告诉编译器:好的,这里有一些东西(方法、类等),可以由给定的名称使用。它只是将给定的名称绑定到某个东西上 定义:它告诉编译器:好的,下面是方法、类等实际做什么(以及如何做)。如果定义了某个对象,那么编译器将实际为其分配空间 你可以看看。嗯,问题不是很清楚。 但是,提供的代码声明了一个类test,并在下面定义它,省略了实际的成员(…)。第一行是所谓的

以下内容的描述或含义是什么: 例如:

class test;

class test
{
  .....
};
首先声明类,然后定义它

声明:它只是告诉编译器:好的,这里有一些东西(方法、类等),可以由给定的名称使用。它只是将给定的名称绑定到某个东西上

定义:它告诉编译器:好的,下面是方法、类等实际做什么(以及如何做)。如果定义了某个对象,那么编译器将实际为其分配空间


你可以看看。

嗯,问题不是很清楚。
但是,提供的代码声明了一个类
test
,并在下面定义它,省略了实际的成员(…)。

第一行是所谓的前向声明。它将类的名称引入当前名称空间,而不实际定义它。

简单的答案是,当您使用第一种形式时,您可以保留指向类的指针或引用,而不需要完整的实现。当两个类紧密交互且它们的实现或定义很难分离时,这非常有用。

C++(如C)被设计为可由单通道编译器实现。如果编译器需要在实际定义类之前知道某个符号引用了某个类,则需要进行正向引用。典型的例子是两个类需要包含指向彼此的指针。i、 e

class B;

class A {
  B* b;
};

class B {
  A* a;
};
如果没有对B的正向引用,编译器将无法成功解析A的定义,您也无法通过将B的定义放在A之前来解决此问题

在像C#这样需要两次编译的语言中,不需要前向引用

class A {
  B b;
}

class B {
  A a;
}

因为编译器的第一个过程只是拾取所有符号定义。当编译器进行第二次传递时,它可以说“我知道B是一个类,因为我在第一次传递时看到了定义”。

如果要访问某个类的成员/方法,或者需要知道该类的大小,编译器需要该类的定义。在其他情况下,提前声明就足够了。这样可以节省编译时间。 例如:

class A { 
  B m_b; 
  C* m_ptrC;
}; 
对于这个类,您需要B的定义(需要大小)和C的声明(指针具有固定大小)。您只需要包含B的头,而不是C的头。C的前向声明就足够了

a、 h:

请记住,如果使用前向声明,则不能使用任何有关大小和方法的信息。这也是两个类相互包含的情况(一个类不需要向前引用)。我个人认为循环引用是不好的风格,如果可能的话,你应该避免它们

有关更多信息:


感谢您对循环依赖项的评论,我只是忘记了它们。

下次您可能想要一个实际上是标题的标题:)将您的问题编辑为一个有意义的标题。这似乎是的副本,因为是副本而关闭。编译器的使用效率是合法的,但我认为循环引用用法是一个更好的起点,当考虑到正向引用的目的。“LaZe:我不知道GCC的细节,但是大多数现代C+C++编译器使用多遍。它们只对实际的源代码进行一次转换,并将其转换为某种内部表示形式。然后在代码生成过程之前,他们在这个内部表示上进行一次或(通常)多次优化过程。我认为多重过程是用于解析的,对于C和C++来说,如果只解决汇编代码编译中的标签需要编译器两次传递,那么C和C++就期望编译器在类范围内是单程的,这是很奇怪的。程序员需要一个特定的声明顺序,这似乎太麻烦了。
#ifndef A_H
#define A_H

#include <b.h>
class C;

class A
{
  B m_b;
  C* m_ptrC;
}
#endif
class B;

class A {
 B* m_ptrB;
}

class B {
 A* m_ptrA;
}