前向声明
外观
在程序设计中,前向声明(Forward Declaration)是指提前声明,但还没有给出完整的定义的标识符(表示编程的实体,如数据类型、变量、函数)。
例子
[编辑]一个简单的C/C++例子:
void printThisInteger(int);
在C++中, 上行代码是一个函数的前向声明,也是该函数的原型。编译器处理该行源码后,允许程序员在随后的程序中引用函数printThisInteger
; 不过程序员必须在某处提供这个被声明的函数的定义:
void printThisInteger(int x) {
printf("%d\n", x);
}
在Pascal与其它Wirth型的编程语言中, 一般规则是所有实体必须在使用前被声明. C语言适用同样的规则, 但存在未声明的函数与不完备的数据类型这样的特例. 因此,C语言允许(虽然不够明智)实现一对互递归函数:
// 前向声明
int second(int);
int first(int x) {
if (x == 0)
return 1;
return second(x-1);
}
int second(int x) {
if (x == 0)
return 0;
return first(x-1);
}
在Pascal程序中, 同样的实现要求在first
引用second
前,必须有一个second
的前向声明. 如果没有这个前向声明, 编译器将产生编译错误,指出标识符second
未经声明即被使用.
前向引用
[编辑]前向引用(英语:forward reference)有时被用作前向声明的同义词[1]。但是,它更经常被用作一个实体在声明前即被实际使用; 例如, 上述代码中second
第一次使用就是前向引用[2][3]。因此,可以说在Pascal中, 前向声明是强制要求,前向引用是被禁止的.
C++中前向引用的例子:
class C {
public:
void mutator(int x) { myValue = x; }
int accessor() { return myValue; }
private:
int myValue;
};
在此例中,对myValue
的两次引用早于它的声明. C++一般禁止前向引用, 但是允许在类成员的特殊场合下使用前向引用。因此,成员函数accessor
不能被编译直到编译器获知成员变量myValue
的类型, 编译器有责任记住accessor
的定义直到它看到myValue
的声明.
允许前向引用大大增加了编译器的复杂度与内存需求,并且使它不能成为一次通过型的编译器。
参考资料
[编辑]- ^ MSDN: Converting to a Forward-Reference Class Type. [2011-08-01]. (原始内容存档于2008-03-28).
- ^ 存档副本 (PDF). [2011-08-01]. (原始内容存档 (PDF)于2016-03-03).
- ^ Thinking in C++: Inlines & the compiler. [2011-08-01]. (原始内容存档于2011-07-09).