类静态变量的初始化

static成员变量属于类,不属于某个具体对象
class A {
public:
	static int value;
};

静态成员变量是一种特殊的成员变量,他被关键字static修饰,这个变量会被当前类所有,无论创建多少A对象内存中都只有一个value变量

类的静态数据为什么要初始化?

因为静态成员变量在类中仅仅是声明,没有定义,所以要在类外定义,实际是给静态成员变量分配内存

class A {
public:
	static int value;
};

上面代码声明了静态成员变量value但是没有对value进行定义,也就是没有分配内存,不可以访问

int A::value = 3;

定义静态成员变量,也可以写成int A::value;虽然不给初值,但是因为分配了内存也可以通过编译

初始化时可以赋初值,也可以不赋值。如果不赋值,那么会被默认初始化为 0。全局数据区的变量都有默认的初始值 0,而动态数据区(堆区、栈区)变量的默认值是不确定的,一般认为是垃圾值。

static成员变量是在初始化时分配内存的,不是类声明的时候也不是创建对象时,没有初始化的static成员变量无法使用,因为没有分配内存

静态成员的类内初始化

通常情况下,静态成员不应该在类内初始化然而我们可以为静态成员提供const整数类型的初始值,不过要求静态成员必须是字面量常量类型的constexpr,初始值必须是常量表达式,因为这些成员本身就是常量表达式所以他们能用在所有适合常量表达式的地方

class Account {
public:
    static double rate() { return interestRate; }
    static void rate(double);
private:
    static constexpr int period = 30;	//period是常量表达式
    double daily_tbl[period];
};

如果某个静态成员的应用场景仅限于编译器可以替换它值的情况则一个初始化的constconstexpr static不需要分别定义,相反,如果我们将它用于值不能替换的场景中,则该成员必须有一条定义语句。

例如,如果period的唯一用途就是定义daily_tbl的维度,则不需要在Account外面专门定义period。此时,如果我们忽略了这条定义,那么对程序非常微小的改动也可能造成编译错误,因为程序找不到该成员的定义语句。举个例子,当需要把Account : :period传递给一个接受const int&的函数时,必须定义period。

  • 即使一个常量静态数据成员在类内部被初始化了,通常情况下也应该在类外部定义一下该成员

类内部已经指定初始值,成员定义就不需要指定了

constexpr int Account::period;

参考

关于C++类的静态数据为什么一定要初始化

《c++ Primer》