A 宣言引入标识符并描述其类型,无论是类型、对象还是函数。声明是编译器需要什么接受对该标识符的引用。这些是声明:
extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for type declarations
A 定义实际上实例化/实现了这个标识符。它是链接器需要什么以便将引用链接到这些实体。这些是与上述声明相对应的定义:
int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};
可以使用定义来代替声明。
标识符可以是declared只要你愿意就可以。因此,以下内容在 C 和 C++ 中是合法的:
double f(int, double);
double f(int, double);
extern double f(int, double); // the same as the two above
extern double f(int, double);
然而,它必须是defined正好一次。如果您忘记定义已在某处声明和引用的内容,则链接器不知道将引用链接到什么,并抱怨缺少符号。如果您多次定义某个内容,则链接器不知道which链接引用的定义并抱怨重复的符号。
自从争论什么是类宣言与一个类定义在 C++ 中不断出现(在其他问题的答案和评论中),我将在此处粘贴 C++ 标准的引用。
在 3.1/2 时,C++03 说:
声明就是定义,除非它[...]是类名声明[...]。
3.1/3 然后给出了一些例子。其中:
[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b [...]
struct S; // declares S
—end example
总结一下:C++ 标准考虑struct x;
成为一个宣言 and struct x {};
a 定义。 (换句话说,“前瞻性声明”用词不当,因为 C++ 中没有其他形式的类声明。)
谢谢约翰内斯·绍布 (Johannes Schaub)谁在他的一个答案中挖出了实际的章节和诗句。