在 C++ 中,声明(Declaration) 与 定义(Definition) 的区别,本质上可以归结为一句话:
声明:告诉编译器"这个名字存在";
定义:为这个名字"分配实体并(通常)提供实现"。
但在实际编程中,这一差异涉及链接(linkage)、存储分配、编译单元组织等多个关键机制,下面系统展开。
一、核心区别(语义层)
| 维度 | 声明(Declaration) | 定义(Definition) |
|---|---|---|
| 作用 | 引入符号 | 创建实体 |
| 是否分配内存 | ❌ 不分配 | ✅ 分配(变量/对象) |
| 是否提供实现 | ❌ 不提供 | ✅ 提供(函数/类) |
| 是否可重复 | ✅ 可多次声明 | ❌ 通常只能定义一次(ODR) |
二、变量:最直观的区别
1. 声明(不分配内存)
cpp
extern int x;
含义:
-
告诉编译器:
x存在 -
不分配内存
-
常用于跨文件引用
2. 定义(分配内存)
cpp
int x = 10;
含义:
-
创建变量
x -
分配存储空间
-
可选初始化
👉 一个程序中必须满足:
每个变量只能有一个定义,但可以有多个声明
三、函数:声明 vs 定义
1. 函数声明(函数原型)
cpp
int add(int a, int b);
作用:
-
告诉编译器函数签名
-
用于提前使用(尤其头文件)
2. 函数定义(实现)
cpp
int add(int a, int b) {
return a + b;
}
作用:
-
提供函数体
-
生成实际代码
👉 注意:
函数声明可以多次出现,但定义只能有一次(否则违反 ODR)。
四、类:一个"特殊情况"
cpp
class A {
public:
void f();
};
这是:
✅ 定义(definition)
❗ 同时也是声明
原因:
-
类定义本身并不分配对象内存
-
但它完整描述了类型结构
👉 所以类的规则是:
-
类本身只能定义一次
-
成员函数可以单独定义
五、总结
声明(Declaration):
-
引入名字
-
不分配资源
-
可重复
定义(Definition):
-
创建实体
-
分配内存或提供实现
-
只能出现一次(ODR约束)
六、从编译器视角再看一句话总结
-
声明:进入符号表(symbol table)
-
定义:进入符号表 + 生成实体(内存/代码)