协慌网

登录 贡献 社区

定义和声明之间有什么区别?

两个人的意思都没有。

答案

声明引入标识符并描述其类型,无论是类型,对象还是函数。声明是编译器接受对该标识符的引用所需的 。这些是声明:

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

定义实际上实例化 / 实现此标识符。这是链接器将引用链接到这些实体所需的内容。这些是与上述声明相对应的定义:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

可以使用定义来代替声明。

可以根据需要随时声明标识符。因此,以下内容在 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);

但是,它必须只定义一次。如果您忘记定义已在某处声明和引用的内容,则链接器不知道链接引用的内容和抱怨缺少的符号。如果您多次定义某些内容,则链接器不知道将哪些定义链接引用并抱怨重复的符号。


由于辩论什么是 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;成为声明struct x {};一个定义 。 (换句话说, “前向声明” 用词不当 ,因为 C ++ 中没有其他形式的类声明。)

感谢litb(Johannes Schaub)在他的一个答案中挖出了实际的章节和经文。

从 C ++ 标准 3.1 节:

声明将名称引入翻译单元或重新声明先前声明引入的名称。声明指定了这些名称的解释和属性。

下一段说明(强调我的)声明是一个定义,除非......

... 它声明了一个函数而没有指定函数的主体

void sqrt(double);  // declares sqrt

... 它在类定义中声明了一个静态成员

struct X
{
    int a;         // defines a
    static int b;  // declares b
};

... 它声明了一个类名

class Y;

... 它包含没有初始值设定项或函数体的extern关键字

extern const int i = 0;  // defines i
extern int j;  // declares j
extern "C"
{
    void foo();  // declares foo
}

... 或者是typedefusing语句。

typedef long LONG_32;  // declares LONG_32
using namespace std;   // declares std

现在有一个重要原因,为什么理解声明和定义之间的区别很重要: 一个定义规则 。从 C ++ 标准的 3.2.1 节:

任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义。

声明:“某处,有一个 foo。”

定义:“...... 就在这里!”