声明与定义
一个类型 (即class)的识别, 分为: (定义) 与 (声明) 暂不提实现, 因为实现是基于(定义)来的
(声明), 也称为: 前置声明forward, 简称fwd
class Foo;
(定义), 即包含这个类的 “所有东西”
class Foo{
int data;
void func();
}
既然, (声明) 和 (定义), 都可以 让编译器 识别/知道 这个类型, 那么, 该用哪一个呢?
(定义) > (声明), 使用(声明)的场景 你写成他的(定义), 肯定没有错; 但反过来不一定成立
对于: Foo f
这样一句话
- 1, 假如他出现在: (全局域 或 函数里), 即意味着: 使用(无参构造函数), 申请一个
f
的变量 - 2, 假如他出现在: (类的成员变量), 因为 类的默认构造函数/类的默认初始化列表, 都会调用 成员变量的默认构造函数
所以, 这种情况, 也意味着: 使用(无参构造函数), 申请一个f
的变量 - 3, 出现在(函数返回值) 或 (函数参数), 且 如果这个函数 只是(声明), 没有函数体的话
意味着: 只是传递一个Foo
类型对象而已, 并不涉及到 构造函数/内存申请
此时, 对应为: 只是有Foo
这样的一个类型而已, 不涉及内存对象申请
可以发现, 1 和 2
对应的情况是相同的, 即 需要申请内存
而申请内存, 必须知道 这个对象的size是多大, 怎么知道一个类型的size呢?
此时, 必须知道 Foo的(定义), 因为(定义)里 有所有的data, 自然可以知道他的size; 而(声明)里没有data;
而3
情况, 他没有在构造对象, 3情况中的函数 只是声明 没有实现体, 此时, 需要Foo的(声明) 就足够了
再附加几种情况:
extern Foo f;
,我们知道, 如果去掉extern, 必须要有(定义)
而此时, 只是extern, 并不会构造对象; 所以此时, 只需要声明
即可Foo * f;
在函数/类成员变量时 ,我们知道, 如果去掉*, 必须要有(定义)
但, 他是一个指针, 并没有构造对象!!! 此时, 只需要声明
即可
综上
static Bar b; ' 需要有 (定义) '
Bar b; ' 需要有 (定义) '
extern Bar b; ' 需要有 (声明) '
extern Bar func(); ' 需要有 (声明) '
extern void func