在 .h 中,如果我有:
#pragma once
#include <xxxx.h>
#include "yyyy.h"
class AAAAAA;
class BBBBBB;
class ZZZZZZ
{
public:
// etc
};
使用 AAAAAA 级;是向前宣布一个班级吗?
为什么要这样做?
需要吗?
有什么好处?缺点?
在 .h 中,如果我有:
#pragma once
#include <xxxx.h>
#include "yyyy.h"
class AAAAAA;
class BBBBBB;
class ZZZZZZ
{
public:
// etc
};
使用 AAAAAA 级;是向前宣布一个班级吗?
为什么要这样做?
需要吗?
有什么好处?缺点?
为什么要这样做?
因为编译器只知道已声明的名称。所以如果你想使用一个类,你必须声明它。但是如果它的定义依赖于它的用户,那么如果用户不依赖于类的定义,而只依赖于它的声明(=名称),那么前向声明就足够了。
特别是,如果用户只需要一个指针或引用,它不依赖于定义。但是在列出的情况下(不声称是排他性的,因为它是标准的非规范摘录),用户依赖于类 T 的定义,如果
在这些情况下,前向声明是不够的,您需要完全定义它。
需要吗?
是的,在需要的情况下需要它。在以下情况下是这样,因为两个类相互引用。
class A;
class B {
// forward declaration needed
void f(A);
};
class A {
void f(B);
};
// "- a function with a return type or argument type of type T is defined"
void B::f(A) {
}
成员函数定义不仅需要声明,还需要类 A 的定义。
有什么好处?缺点?
好处是您的程序可以编译。缺点是您已经用另一个名称污染了范围。但这是它必要的邪恶。
如果您通过引用或指针引用类,编译器需要知道它存在,但仅此而已。因此,您需要做的就是前向声明它。
如果文件调用类的方法或引用对象实例(不是引用或指针),则必须使用#include 拉入该类型的定义。
在大型代码库中,最小化 #includes 会减少编译时间。
前向声明还有助于避免循环#include 问题。
如果您只打算引用该类型,则无需拉入定义它的整个标头,只需使用前向声明告诉编译器“这是已定义的”,以便编译器在该文件中使用它时,并且无法解析符号,不会吓到你。这是“我知道我在做什么”的事情之一。
当类相互引用时,前向声明是必不可少的。这是一个简单的案例:
class A;
class B {
void f(A&);
};
class A {
void f(B&);
};
如果没有前向声明,您将无法做到这一点。这与当您有两个相互递归的函数时相同,其中一个必须前向声明。