参考:https://blog.csdn.net/qq_34801642/article/details/104948850
实例
2.1 static数据成员
#include
using namespace std;
class A
{
public:
//整型的静态成员
static bool b;
static char c;
static int i;
//浮点型的数据成员
static float f;
static double d;
// static int i1 = 1; // 错误:带有类内初始值设定项的成员必须为常量
// static double d1 = 3.14; // 错误:带有类内初始值设定项的成员必须为常量
};
bool A::b = true;
char A::c = ‘a’;
int A::i = 1;
float A::f = 1.5;
double A::d = 2.5;
int main()
{
cout << A::b << endl;
cout << A::c << endl;
cout << A::i << endl;
cout << A::f << endl;
cout << A::d << endl;
return 0;
}

总结:
一般的static数据成员只能在类内声明,在类外定义和初始化。
2.2 static const数据成员
#include
using namespace std;
class A
{
public:
//整型的静态成员
static const bool b1;
static const char c1;
static const int i1;
//浮点型的数据成员
static const float f1;
static const double d1;
//整型的静态成员
static const bool b2 = false;
static const char c2 = 'b';
static const int i2 = 2;
//浮点型的数据成员
// static const float f2 = 3.5; // 错误:"const float" 类型的成员不能包含类内初始值设定项
// static const double d2 = 4.5; // 错误:"const double" 类型的成员不能包含类内初始值设定项
// char m1[i1];// 错误:i1的常量还未初始化
char m2[i2];
};
const bool A::b1 = true;
const char A::c1 = ‘a’;
const int A::i1 = 1;
const float A::f1 = 1.5;
const double A::d1 = 2.5;
const bool A::b2;
const char A::c2;
const int A::i2;
int main()
{
cout << A::b1 << endl;
cout << A::c1 << endl;
cout << A::i1 << endl;
cout << A::f1 << endl;
cout << A::d1 << endl;
cout << “---------------------------------------” << endl;
cout << A::b2 << endl;
cout << A::c2 << endl;
cout << A::i2 << endl;
return 0;
}

总结:
static const数据成员可以在类内声明,在类外定义和初始化。在类内声明时,static const数据成员还未初始化,不算真正的const。
static const整型数据成员可以在类内声明和初始化,在类外定义。在类内声明和初始化时,static const数据成员是真正的const。
若编译时static const数据成员可用它的值替代(如表示数组个数等),它可以不需要定义。若不能替代(如作为参数等),必须含有一条定义语句。建议不管是否可替代都在类外定义一次。
若static const数据成员不是整型(bool、char、int、short、long等),则不能在类内初始化。
2.3 static constexpr数据成员
#include
using namespace std;
class A
{
public:
//整型的静态成员
// static constexpr bool b1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
// static constexpr char c1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
// static constexpr int i1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
//浮点型的数据成员
// static constexpr float f1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
// static constexpr double d1; // 错误:constexpr 静态数据成员声明需要类内初始值设定项
//整型的静态成员
static constexpr bool b2 = false;
static constexpr char c2 = 'b';
static constexpr int i2 = 2;
//浮点型的数据成员
static constexpr float f2 = 3.5;
static constexpr double d2 = 4.5;
// char m1[i1]; // 错误:i1的常量还未初始化
char m2[i2];
};
// constexpr bool A::b1 = true;
// constexpr char A::c1 = ‘a’;
// constexpr int A::i1 = 1;
// constexpr float A::f1 = 1.5;
// constexpr double A::d1 = 2.5;
constexpr bool A::b2;
constexpr char A::c2;
constexpr int A::i2;
constexpr float A::f2;
constexpr double A::d2;
int main()
{
cout << A::b2 << endl;
cout << A::c2 << endl;
cout << A::i2 << endl;
cout << A::f2 << endl;
cout << A::d2 << endl;
return 0;
}

总结:
static constexpr数据成员必须在类内声明和初始化。在类内声明和初始化时,static constexpr数据成员是真正的const。
若编译时static constexpr数据成员可用它的值替代(如表示数组个数等),它可以不需要定义。若不能替代(如作为参数等),必须含有一条定义语句。建议不管是否可替代都在类外定义一次。
若static constexpr数据成员即使不是整型,也可进行类内初始化时。