首页 > 代码库 > C++类特殊成员变量(引用、静态、常成员变量)的初始化操作

C++类特殊成员变量(引用、静态、常成员变量)的初始化操作

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

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 const int csi;                   // 静态常量成员变量  
     static const int csi2 = 100;            // 静态常量成员变量的初始化(Integral type)    (1)  
     static const double csd;                // 静态常量成员变量(non-Integral type)  
     //static const double csd2 = 99.9;      // error: 只有静态常量整型数据成员才可以在类中初始化  
    };  
      
    //注意下面三行:不能再带有static  
    int BClass::si = 0; // 静态成员变量的初始化(Integral type)  
    const int BClass::csi = 1; // 静态常量成员变量的初始化(Integral type)  
    const double BClass::csd = 99.9; // 静态常量成员变量的初始化(non-Integral type)  
      
    // 在初始化(1)中的csi2时,根据著名大师Stanley B.Lippman的说法下面这行是必须的。  
    // 但在VC2003中如果有下面一行将会产生错误,而在VC2005中,下面这行则可有可无,这个和编译器有关。  
    const int BClass::csi2;  
      
    int main()  
    {  
         BClass b;  
         return 0;  
    }  
静态成员属于类作用域,但不属于类对象,和普通的static变量一样,程序一运行就分配内存并初始化,生命周期和程序一致。
所以,在类的构造函数里初始化static变量显然是不合理的。
静态成员其实和全局变量地位是一样的,只不过编译器把它的使用限制在类作用域内(不是类对象,它不属于类对象成员),要在类的定义外(不是类作用域外)初始化。


下面再说说成员变量是引用的情况:
因为引用是别名的意思,所以定义应用肯定是外部有定义,然后在构造函数初始化列表中被初始化的

    #include <iostream>
    using namespace std;
    class A
    {
    public:
        A(int i=3):m_i(i){}
        void print()
        {
            cout<<"m_i="<<m_i<<endl;
        }
    private:
        int m_i;
    };
    class B
    {
    public:
        B(){}
        B(A& a):m_a(a){}
        void display()
        {
            m_a.print();
        }
    private:
        A& m_a;
    };
    int main(int argc,char** argv)
    {
        A a(5);
        B b(a);
        b.display();
        return 0;
    }


这样B中就可以有a这个对象了,

[注意]:引用类型成员变量的初始化:

    1,不能直接在构造函数里初始化,必须用到初始化列表,且形参也必须是引用类型。

    2,凡是有引用类型的成员变量的类,不能有缺省构造函数。原因是引用类型的成员变量必须在类构造时进行初始化。
    3,如果两个类要对第三个类的数据进行共享处理,可以考虑把第三个类作为这两个类的引用类型的成员变量。





C++类特殊成员变量(引用、静态、常成员变量)的初始化操作