c++primer这本书好像没提到这个问题,好像应该是声明?那静态成员的初始化是定义还是声明?static constexpe int a=30,在类中这条语句也是声明吗?如果是定义,那在类外再定义一次,constexpr int 类名: :a,不就是重复定义了?
这与c++关键字constexpr、const也有关,不用过于深究。
你的理解是对的,对于一般的只用static修饰的成员是不可以在类内初始化的,只能在类中声明。
但这里是加了constexpr关键字,这需要你去了解它,并在代码中进行试验。
1.一般static类内成员变量
class A {
public:
static int i1;
static bool b1;
static char c1;
static float f1;
static double d1;
//以下错误,不能将一般static类型的变量在类内初始化,只能进行声明
//static int i2 = 2;
//static bool b2 = true;
//static char c2 = 'c';
//static float f2 = 3.1;
//static double d2 = 3.2;
};
int A::i1 = 1;
bool A::b1 = true;
char A::c1 = 'c';
float A::f1 = 3.3;
double A::d1 = 3.4;
2.static const类内成员变量
class A {
public:
static const int i1;
static const bool b1;
static const char c1;
static const float f1;
static const double d1;
//整形类型的static const变量可以在类内初始化
static const int i2 = 2;
static const bool b2 = true;
static const char c2 = 'c';
//以下错误,不能将static const类型的变量在类内初始化,只能进行声明
//static const float f2 = 3.1;
//static const double d2 = 3.2;
};
const int A::i1 = 1;
const bool A::b1 = true;
const char A::c1 = 'c';
const float A::f1 = 3.3;
const double A::d1 = 3.4;
3.static constexpr类内成员变量
class A {
public:
//以下错误,static constexpr类型变量必须在类内定义与初始化
//static constexpr int i1;
//static constexpr bool b1;
//static constexpr char c1;
//static constexpr float f1;
//static constexpr double d1;
//整形和浮点型类型的static const变量必须在类内初始化
static constexpr int i2 = 2;
static constexpr bool b2 = true;
static constexpr char c2 = 'c';
static constexpr float f2 = 3.1;
static constexpr double d2 = 3.2;
};
//以下错误,static constexpr类型变量不能在类外初始化
//constexpr int A::i1 = 1;
//constexpr bool A::b1 = true;
//constexpr char A::c1 = 'c';
//constexpr float A::f1 = 3.3;
//constexpr double A::d1 = 3.4;
你可以看看ODR(One Definition Rule)
https://en.cppreference.com/w/cpp/language/definition
关于这个点,我的理解是你应该理解static的特性,存储在静态存储区中,并且一开始的时候就会进行初始化。
而静态成员这里就要结合static的特性去做特殊的理解了。 类是对象,而对象实例化才会真正对类成员做初始化,与static特性矛盾,所以,要专门在外面用类名::static成员进行初始化。
至于声明和定义的概念,随便百度了,声明只是命名,而定义是分配空间,除此之外还要做初始化。