例如,在下面的示例中,如果在定义类之前声明类,将会获得什么额外的好处呢?
class test;
class test
{
.....
};
例如,在下面的示例中,如果在定义类之前声明类,将会获得什么额外的好处呢?
class test;
class test
{
.....
};
C++(类似于C语言)的设计目标是可以被单遍编译器实现。在编译器需要在类实际定义之前知道符号引用一个类的情况下,需要使用前向引用。其中经典的例子是当两个类需要包含指向彼此的指针时。
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;
};
a.h:
#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;
}
请记住 - 如果您使用前向声明,就不能使用任何有关大小和方法的信息。如果两个类相互包含(其中一个类不需要前向引用),也是如此。我个人认为循环引用是不好的风格,如果可能的话应该避免使用。
有关更多信息:C++ FAQ
感谢您提供有关循环依赖的评论,我简单地忘记了它们。
首先,类被声明,然后被定义。
声明:它只是告诉编译器:好的,这里有个东西(方法、类等),可以用给定的名称。它只将给定的名称与某些东西“绑定”起来。
定义:它告诉编译器:好的,这里是方法、类等实际上如何执行它们的任务的内容和方式。如果定义了某些东西,则编译器会为其实际分配空间。
你可以在这里查看。
第一行是所谓的前向声明。它将类的名称带入当前命名空间,但并不实际定义它。
test
的类,并在下面定义它,省略了实际成员(...)。