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;
}