初始化静态数据成员

Initialization of static data member

本文关键字:数据成员 静态 初始化      更新时间:2023-10-16

为什么不进行静态数据成员的默认初始化?在下面的示例

struct data_member
{
    data_member(){ cout << "data_membern"; }
    ~data_member(){ cout << "~data_membern"; }
};
struct Y
{
    static data_member m;
    Y(){ cout << "Yn"; }
    ~Y(){ cout << "~Yn"; }
};
Y y; //call constructor of Y 

但是如果我们从data_member m中删除static的说明符,它将被默认初始化。

struct data_member
{
    data_member(){ cout << "data_membern"; }
    ~data_member(){ cout << "~data_membern"; }
};
struct Y
{
    data_member m;
    Y(){ cout << "Yn"; }
    ~Y(){ cout << "~Yn"; }
};
Y y; //call Y() and data_member()

静态成员必须在类定义之外定义。它将被初始化(也可以默认初始化)。

以下标准草案中关于static成员变量的描述应该可以解释为什么在类声明中没有默认初始化。

9.4.2静态数据成员

2 static数据成员在其类定义中的声明不是定义,可能是不完整的类型,而不是cv-qualified voidstatic数据成员的定义应该出现在包含该成员类定义的命名空间作用域中。在命名空间作用域的定义中,static数据成员的名称应使用::操作符由其类名限定。

struct Y
{
    static data_member m;
    Y(){ cout << "Yn"; }
    ~Y(){ cout << "~Yn"; }
};

只有声明了 m。对于编译器来说,Y::m是在另一个翻译单元中定义的。由于静态数据成员每个类一个,你必须能够声明它们而不定义它们,否则当你在不同的翻译单元中包含头文件时,你将无法在不违反单一定义规则的情况下将类定义放在头文件中。

data_member Y::m;

这定义了m,并将导致构造函数调用。

static数据成员class定义中声明。它们需要定义(一次)在此之外,通常在相应的cpp文件中:

data_member Y::m;

在这里你会看到它的默认函数名为

基本答案:类成员就像函数一样。我们有声明和定义。你在类级别"声明"它们的存在,而"定义"是由构造函数完成的。而静态成员则更加复杂。它们不是"与实例相关的",构造函数也不会"定义"它们。你必须在类外自己做:

Type CLASS::member;

顺便说一句,使用静态成员是非常糟糕的做法。

使用静态函数代替:

class Foo{
public:
     Type &getMember(){
         static Type member;
         return member;
     }
};