C++重要性质06:静态成员

来源:互联网 发布:富木制衣淘宝旗舰店 编辑:程序博客网 时间:2024/06/04 18:46

   序:大学四年浑浑噩噩,光阴虚度;值此毕业之际,如梦方醒;然亦无所悔恨,既有所悟,惟勤勉耳。近来研习《深入浅出MFC》,受益良多,故而摘抄一二,置此博文之中,以备不时翻阅。小子不才,无所增益,学而践之而已。此文摘自《深入浅出MFC》第二章C++的重要性质。  
    【静态成员变量/函数】

     如果依据一个类别产生出三个对象,每一个对象将各有一份成员变量,但有时候这并不是我们想要的。

     假设有一个类别,专门用来处理存款帐户,它至少应该要有存户的姓名、地址、存款额、利率等成员变量:

            classCSavingAccount
             {
             private:
                   char     m_name[40]; // 存戶姓名
                   char     m_addr[60]; // 存戶住址
                   double m_total; // 存款額
                   double m_rate; // 利率
                   ......

             };

     如果这家银行采用浮动利率,每个帐户的利息都是根据当天的挂牌利率来计算。这时候m_rate就不适合成为每个帐户对象中私有的一项数据,否则每天一开市,光把所有帐户内容叫出来,修改m_rate的值,就得花掉不少时间。m_rate应该独立在各对象之外,成为类别独一无二的数据。怎么做?在m_rate前面加上static修饰词,将其声明为静态成员即可:

            classCSavingAccount
             {
             private:
                   char     m_name[40]; // 存戶姓名
                   char     m_addr[60]; // 存戶住址
                   double m_total; // 存款額
                  
staticdouble m_rate;// 利率
                   ......

             };

     静态成员变量不属于对象的一部份,而是类别的一部份,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量,但首先必须初始化它。

     不要把static 成员变量的初始化操作安排在类别的构造函数中,因为构造函数可能一再被调用,而变量的初值却只应该设定一次。也不要把初始化操作安排在头文件中,因为头文件可能会被包含在许多地方,因此也就可能被执行多次。应该在源文件中且类别以外的任何位置设定其初值。例如在main()之中,或全局函数中,或任何函数之外:

              doubleCSavingAccount::m_rate = 0.0075;// 设定 static 成员变量的初值
               void main() { ... }

     设定静态成员变量初值时,不受任何存取权限的束缚。请注意,静态成员变量的数据类型也出现在初值设定句中,因为这是一个初值设定动作,不是一个赋值(assignment)动作。事实上,静态成员变量是在这时候(而不是在类声明中)才定义出来的。如果没有初始化操作,会产生链接错误(error LNK2001)。

    下面是存取静态成员变量的一种方式,注意,此刻还没有定义任何对象实体:

           // 第一种存取方式
            void main()
            {
                   CSavingAccount::m_rate = 0.0075;// 欲此行成立,须把 m_rate 改为public
            }

    下面这种情况则是产生一个对象后,通过对象来处理静态成员变量:

           // 第二种存取方式
            void main()
            {

                   CSavingAccount myAccount;

                   myAccount.m_rate = 0.0075; // 欲此行成立,须把 m_rate 改为public
            }

     这里得强调一个概念:静态成员变量并不是因为对象的实现才得以实现,它本来就存在。你可以想象它是一个全局变量,因此,第一种处理方式在意义上比较不会给人错误的印象。

     只要access level允许,任何函数(包括全局函数或成员函数,静态函数或非静态函数)都可以存取静态成员变量。但如果希望在产生任何对象之前就存取其class的私有静态成员变量(private static member variable),则必须设计一个静态成员函数(例如以下的setRate()):

            classCSavingAccount
             {
             private:
                   char     m_name[40]; // 存戶姓名
                   char     m_addr[60];  // 存戶住址
                   double m_total;          // 存款額
                  
staticdouble m_rate;// 利率
                   ......

            public:
                   static void setRate(double newRate) { m_rate = newRate; }
                   ......
             };

             //-------------------------------------------------------------
                   doubleCSavingAccount::m_rate = 0.0075;// 设定 静态成员变量的初值

            void main()
            {

                   CSavingAccount::setRate(0.0075); // 直接调用类別的静态成员函数

                   CSavingAccountmyAccount;
                   myAccount
.setRate (0.0075); // 通过对象调用静态成员函数
            }

     由于静态成员函数不需要借助任何对象,就可以被调用执行,所以编译器不会为它暗加一个this指针。也因为如此,静态成员函数无法处理类别之中的非静态成员变量







0 0