C++自学笔记_特殊的成员变量的初始化方法_《C++ Primer》

有些成员变量的数据类型比较特别,它们的初始化方式也和普通数据类型的成员变量有所不同。这些特殊的类型的成员变量包括:

a.引用

b.常量

c.静态

d.静态常量(整型)

e.静态常量(非整型)

   

常量和引用,必须通过参数列表进行初始化。


静态成员变量的初始化也有点特别,是在类外初始化且不能再带有static关键字。

 

#include <iostream>

using namespace std;

class BClass{
public:
    BClass():i(1),ci(2),ri(i){}   //对于常量型成员变量或者引用型成员变量,必须要用构造函数初始
                                  //化列表初始化;对于普通成员变量,其本质已经是赋值了,效率也低
private:
    int i;                              //普通变量
    const int ci;                       //常量成员变量
    int &ri;                            //引用变量
    static int si;                      //静态成员变量
    //static int si2=100;               //error!!只有静态常量成员变量,才可以初始化
    static int si2;
    static const int sci;               //静态常量成员变量
    static const int sci2=100;          //静态常量成员的初始化
    static const double scd;            //静态常量成员变量
    //static const double scd2=100.0;   //error!!只有静态常量整型数据才可以在类中初始化
};

/*注意下面3行,不能再带有 static */
int BClass::si2=100;
const int BClass::sci=100;
const double BClass::scd=100.0;
const int BClass::sci2;                 //根据著名大师Stanley B.Lippman的说法这行是必须的,
                                        //但这其实和具体的编译器有关。
int main()
{
    BClass B;
    return 0;
}

 

静态成员属于类作用域,但不属于类对象,和普通的static变量一样,程序一运行就分配内存并初始化,生命周期和程序一致。可以这么理解:在类中,只是声明了静态变量,并没有定义。而恰恰是因为仅仅做了声明,所以并不为其分配内存,只有当定义了以后才分配内存。(注意:如果在类里面这么写: int a; 那么是既声明了变量,也定义了变量,两者合在一起了。)

 

静态成员其实和全局变量地位是一样的,是“类级别”的,也就是它和类的地位相同,只不过编译器把它的使用限制在类作用域内(不是类对象,它不属于类对象成员),要在类的定义外(不是类作用域外)初始化。而普通成员是“对象级别”的。类级别的成员,先于该类任何对象的存在而存在,它被该类所有的对象共享。

 

所以,在类的构造函数里初始化static变量显然是不合理的。假定要实例化该类的一个对象,那么会发生什么事情呢?静态成员肯定要出现在这个对象里面的。这时候才去定义那个静态成员吗?这显然是不合适的。因为,比如有另外一个线程也要创建该类的对象,那么也要按照这个方式去定义那个静态成员。这会产生两种可能的情况:1. 重复定义;2. 就算不产生重复定义的情况,也会产生竞争,从而造成死锁的问题,以至于对象无法创建。很显然,编译器不能这么干。那么很合理的解决办法,就是事先在类的外部把它定义好,然后再供所有的对象共享。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。