声明是告知编译器该程序元素的名称以及类型,定义则是使编译器为程序元素分配内存空间。二者最根本的区别就是是否分配内存。声明不会导致内存的分配,而定义会分配内存。在C++程序中声明可以有多次,但是定义只能有一次。因此不能将变量的定义放置于头文件中,由于头文件会被多次引用,就会导致变量在多个源文件中被重复定义,这是C++所不允许的。但是也有例外的情况,以下3种定义可以放入头文件中:
a. 类的定义。
b. const变量的定义。因为const常量的作用域仅限于定义它的文件,所以可以在多个源文件中出现它的定义。
c. inline函数。
声明可以充当为定义,除非是以下几种情况:
a. 函数原型(无函数体的函数声明)。
b. 包含extern关键字并且没有初始化变量、对象或函数体。例如:
extern int i; //声明
extern int p = 123; //定义
c. 没有下列定义的类名声明,如Class T;
d. 类声明中的静态数据成员。例如:
class abc{
static const int i = 10; //常量声明式
int ui[i]; //使用该常量
};
值得注意的是,你看到的是i的声明式而非定义式。C++会要求你为所使用的任何东西提供定义式,但是如果它是class的专属常量且是static且为int类型时,可以区别对待。如果不取它的地址,你可以声明并使用它们而无需提供定义式。但是如果你要取它的地址或是编译器并不认可这种行为,你需要在实现文件中添加如下代码:
const int abc::i;
如果你的编译器不支持以上语法,即不允许static成员在其声明式中获得初值,你可以将初值放在定义式内。
class abc{
static const int i; //常量声明式
......
};
abc::i = 10;
但是如果你的class在编译期间需要一个class常量值,例如编译器需要知道ui数组的大小。这时你可以使用enum来弥补。
class abc{
enum { i = 10 };
int ui[i];
};