所有标准为C11标准,旧的就不看了。
首先说一条指导规则:通常情况下,不应该在类内部初始化成员!!无论是否为静态、是否为常量、是否为int等!!统统不建议在类内初始化,因为本质上类只是声明,并不分配内存,而初始化会分配内存,类内初始化会将两个过程混在一起!
按顺序说。
首先静态成员,用static限制的成员:
在类内初始化静态成员,那么就必须满足如下条件才行:
1) 静态成员必须为字面值常量类型:constexpr。
2)给静态成员提供的初始值,必须为常量表达式。(这条一般都满足,没人闲的找个算式或者变量给其赋值初始化。。。)
下面测试:
一、静态int变量和静态double变量:
static int months1 = 12;
static double pi1 = 3.14;
结果报错:
ISO C++ forbids in-class initialization of non-const static member ‘robin::Student::months1’
static int months1 = 12;
c++禁止在类内初始化非静态常量。对照规则也很明显,不符合第一条。
二、静态int常量和静态double常量
static const int months2 = 12;//静态int常量
这句是没问题的~
static const double pi2 = 3.14;//静态double常量
这句会报错:
error: ‘constexpr’ needed for in-class initialization of static data member ‘const double robin::Student::pi2’ of non-integral type [-fpermissive]
static const double pi2 = 3.14;
类内初始化静态成员时需要constexpr。
从两条规则上看,他们都不满足,因为都不是字面值常量类型constexpr,而是const类型,这两个还是有区别的。
但是static const int不报警而static const double报警,猜测是因为int是之前标准遗留下来的。而之前的标准内并没有const double类型。为了兼容性允许继续可用。。。
三、静态int字面值常量和静态double字面值常量
static constexpr int months3 = 12;
static constexpr double pi3 = 3.14;
OK,完美运行,因为是严格符合按照规则一。
四、非静态int变量和非静态double变量
int months4 = 12;
double pi4 = 3.14;
没毛病~
五、非静态int常量和非静态double常量
int const months4 = 12;
double const pi4 = 3.14;
没毛病~
说一句第一种情况,像这种静态非const 成员,一般在类定义cpp中进行赋值:
//head.h类声明中:
static int months1;
//head.cpp类定义中:
int Student::months1 = 100;//这么赋值,前面要有int类型,然后加类作用域。
其他情况类似的用法也都是可以的,对应好就行。
//head.h类声明中:
static const int months2;
//head.cpp类定义中:
const int Student::months2 = 100;
总之总结两句就是:
1、不建议在类内初始化。
2、静态成员只有一个副本,所有的类对象共用。而非静态成员每个对象有一个副本。
上张图: