class Test
{
int a = 0;// 1 error.
const int a = 0; //2 error.
static int a = 0; //3 error.
static const int a = 0; //4 ok. int/char等可以进行就地初始化,是因为这些变量可以直接被优化为立即数.
};
以上四种变量的定义方式只有4是正确的,原因如下:
error 1:编译器对每个包含该头文件的源文件编译,导致生成多个a的导出符号,则会导致duplicated external simbols。因此如果头文件里要定义,必须保证定义的符号只能具有内部链接。
error2:由于const 变量是内部链接,保证了定义的符号只能具有内部链接的条件,但是每个类对象都会含有一个a成员变量,值均为1,无法对其改变。
error3:由于static 变量是内部链接,保证了定义的符号只能具有内部链接的条件,并且每个包含该头文件的源文件都会生成一个内部符号a,但是a是静态成员变量,是属于类所有的, 一处改变,其他使用的地方都会改变,但是此处不符合该特点,所以编译器不允许类生命中定义静态成员变量。
4:static const因为static,所以属于整个类,因为const所有不可改变,恰恰克服了2,3的问题。
但是为什么不能定义对象呢?如果定义一个对象会怎么样呢?
一般不会怎么样,这个和C里的在头文件里定义static const int一样,每一个包含了这个头文件的编译单元都会定义这个对象。但由于该对象是const的,所以没什么影响。但是:有2种情况可能破坏这个局面:
1)如果涉及到对这个const对象取地址并且依赖于这个地址的唯一性,那么在不同的编译单元里,取到的地址可以不同。(但一般很少这么做)
2)如果这个对象具有mutable的变量,某个编译单元对其进行修改,则同样不会影响到别的编译单元。