• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            asm, c, c++ are my all
            -- Core In Computer
            posts - 139,  comments - 123,  trackbacks - 0

            [轉]靜態成員數據和靜態成員函數

            在沒有講述本章內容之前如果我們想要在一個范圍內共享某一個數據,那么我們會設立全局對象,但面向對象的程序是由對象構成的,我們如何才能在類范圍內共享數據呢?

              這個問題便是本章的重點:

              聲明為static的類成員或者成員函數便能在類的范圍內共同享,我們把這樣的成員稱做靜態成員和靜態成員函數。
              下面我們用幾個實例來說明這個問題,類的成員需要保護,通常情況下為了不違背類的封裝特性,我們是把類成員設置為protected(保護狀態)的,但是我們為了簡化代碼,使要說明的問題更為直觀,更容易理解,我們在此處都設置為public。

              以下程序我們來做一個模擬訪問的例子,在程序中,每建立一個對象我們設置的類靜態成員變自動加一,代碼如下:

            #include <iostream>
            using namespace std;

            class Internet
            {
            public:
            ??? Internet(char *name,char *address)
            ??? {
            ??????? strcpy(Internet::name,name);
            ??????? strcpy(Internet::address,address);
            ??????? count++;
            ??? }
            ??? static void Internet::Sc()//靜態成員函數
            ??? {
            ??????? cout<<count<<endl;
            ??? }
            ??? Internet &Rq();
            public:
            ??? char name[20];
            ??? char address[20];
            ??? static int count;//這里如果寫成static int count=0;就是錯誤的
            };

            Internet& Internet::Rq()//返回引用的成員函數
            {
            ??? return *this;
            }

            int Internet::count = 0;//靜態成員的初始化
            void vist()
            {
            ??? Internet a1("中國軟件開發實驗室","
            www.cndev-lab.com ");
            ??? Internet a2("中國軟件開發實驗室","
            www.cndev-lab.com ");
            }
            void fn(Internet &s)
            {
            ??? cout<<s.Rq().count;
            }
            void main()
            {
            ??? cout<<Internet::count<<endl;//靜態成員值的輸出
            ??? vist();
            ??? Internet::Sc();//靜態成員函數的調用
            ??? Internet b("中國軟件","
            www.cnsoft.com ");
            ??? Internet::Sc();
            ??? fn(b);
            ??? cin.get();
            }

              上面代碼我們用了幾種常用的方式建立對象,當建立新對象并調用其構造函數的時候,靜態成員cout便運行加1操作,靜態成員的初始化應該在主函數調用之前,并且不能在類的聲明中出現,通過運行過程的觀察我們發現,靜態成員count的狀態并不會隨著一個新的對象的新建而重新定義,盡而我們了解到類的靜態成員是屬于類的而不是屬于哪一個對象的,所以靜態成員的使用應該是類名稱加域區分符加成員名稱的,在上面的代碼中就是Internet::count,雖然我們仍然可以使用對象名加點操作符號加成員名稱的方式使用,但是不推薦的,靜態態類成員的特性就是屬于類而不專屬于某一個對象。

              靜態成員函數的特性類似于靜態成員的使用,同樣與對象無關,調用方法為類名稱加域區分符加成員函數名稱,在上面的代碼中就是Internet::Sc();,靜態成員函數由于與對象無關系,所以在其中是不能對類的普通成員進行直接操作的。

              如果上面的 static void Internet::Sc()修改成為:


            static void Internet::Sc()//靜態成員函數
            {
            ??? cout<<name<<endl;//錯誤
            ??? cout<<count<<endl;
            }

              靜態成員函數與普通成員函數的差別就在于缺少this指針,沒有這個this指針自然也就無從知道name是哪一個對象的成員了。

              根據類靜態成員的特性我們可以簡單歸納出幾點,靜態成員的使用范圍:

              1.用來保存對象的個數。

              2.作為一個標記,標記一些動作是否發生,比如:文件的打開狀態,打印機的使用狀態,等等。

              3.存儲鏈表的第一個或者最后一個成員的內存地址。

              為了做一些必要的練習,深入的掌握靜態對象的存在的意義,我們以前面的結構體的教程為基礎,用類的方式描述一個線性鏈表,用于存儲若干學生的姓名,代碼如下:

            #include <iostream>
            using namespace std;

            class Student
            {
            public:
            ??? Student (char *name);
            ??? ~Student();
            public:
            ??? char name[30];
            ??? Student *next;
            ??? static Student *point;
            };

            Student::Student (char *name)
            {
            ??? strcpy(Student::name,name);
            ??? this->next=point;
            ??? point=this;
            }

            Student::~Student ()//析構過程就是節點的脫離過程
            {
            ??? cout<<"析構:"<<name<<endl;

            ??? if(point==this)
            ??? {
            ??????? point=this->next;
            ??????? cin.get();
            ??????? return;
            ??? }
            ??? for(Student *ps=point;ps;ps=ps->next)
            ??? {
            ??????? if(ps->next==this)
            ??????? {
            ??????? cout<<ps->next<<"|"<<this->next<<endl;
            ??????? ps->next=next;//=next也可以寫成this->next;
            ??????? cin.get();
            ??????? return;
            ??????? }
            ??? }
            ??? cin.get();
            }

            Student* Student::point=NULL;
            void main()
            {
            ??? Student *c = new Student("marry");
            ??? Student a("colin");
            ??? Student b("jamesji");
            ??? delete c;
            ??? Student *fp=Student::point;
            ??? while(fp!=NULL)
            ??? {
            ??????? cout<<fp->name<<endl;
            ??????? fp=fp->next;
            ??? }
            ??? cin.get();
            }

              從上面的代碼來看,原來單純結構化編程需要的一個鏈表進入全局指針在這里被類的靜態成員指針所替代(類的靜態成員完全可以替代全局變量),這個例子的理解重點主要是要注意觀察類成員的析構順序,通過對析構順序的理解,使用析構函數來進行節點的脫鏈操作。

            靜態成員的提出是為了解決數據共享的問題。實現共享有許多方法,如:設置全局性的變量或對象是一種方法。但是,全局變量或對象是有局限性的。這一章里,我們主要講述類的靜態成員來實現數據的共享。

              靜態數據成員

              在類中,靜態成員可以實現多個對象之間的數據共享,并且使用靜態數據成員還不會破壞隱藏的原則,即保證了安全性。因此,靜態成員是類的所有對象中共享的成員,而不是某個對象的成員。

              使用靜態數據成員可以節省內存,因為它是所有對象所公有的,因此,對多個對象來說,靜態數據成員只存儲一處,供所有對象共用。靜態數據成員的值對每個對象都是一樣,但它的值是可以更新的。只要對靜態數據成員的值更新一次,保證所有對象存取更新后的相同的值,這樣可以提高時間效率。

              靜態數據成員的使用方法和注意事項如下:

              1、靜態數據成員在定義或說明時前面加關鍵字static。

              2、靜態成員初始化與一般數據成員初始化不同。靜態數據成員初始化的格式如下:

                <數據類型><類名>::<靜態數據成員名>=<值>

              這表明:

            ?????   (1) 初始化在類體外進行,而前面不加static,以免與一般靜態變量或對象相混淆。

              (2) 初始化時不加該成員的訪問權限控制符private,public等。

              (3) 初始化時使用作用域運算符來標明它所屬類,因此,靜態數據成員是類的成員,而不是對象的成員。

              3、靜態數據成員是靜態存儲的,它是靜態生存期,必須對它進行初始化。

              4、引用靜態數據成員時,采用如下格式:

               <類名>::<靜態成員名>

              如果靜態數據成員的訪問權限允許的話(即public的成員),可在程序中,按上述格式來引用靜態數據成員。

              下面舉一例子,說明靜態數據成員的應用:

            #include
            class Myclass
            {
            public:
            Myclass(int a, int b, int c);
            void GetNumber();
            void GetSum();
            private:
            int A, B, C;
            static int Sum;
            };

            int Myclass::Sum = 0;

            Myclass::Myclass(int a, int b, int c)
            {
            A = a;
            B = b;
            C = c;
            Sum += A+B+C;
            }

            void Myclass::GetNumber()
            {
            cout<<"Number="< }

            void Myclass::GetSum()
            {
            cout<<"Sum="< }

            void main()
            {
            Myclass M(3, 7, 10),N(14, 9, 11);
            M.GetNumber();
            N.GetNumber();
            M.GetSum();
            N.GetSum();
            }


              從輸出結果可以看到Sum的值對M對象和對N對象都是相等的。這是因為在初始化M對象時,將M對象的三個int型數據成員的值求和后賦給了Sum,于是Sum保存了該值。在初始化N對象時,對將N對象的三個int型數據成員的值求和后又加到Sum已有的值上,于是Sum將保存另后的值。所以,不論是通過對象M還是通過對象N來引用的值都是一樣的,即為54。
            靜態成員函數

              靜態成員函數和靜態數據成員一樣,它們都屬于類的靜態成員,它們都不是對象成員。因此,對靜態成員的引用不需要用對象名。

              在靜態成員函數的實現中不能直接引用類中說明的非靜態成員,可以引用類中說明的靜態成員。如果靜態成員函數中要引用非靜態成員時,可通過對象來引用。下面通過例子來說明這一點。

            #include
            class M
            {
            public:
            M(int a) { A=a; B+=a;}
            static void f1(M m);
            private:
            int A;
            static int B;
            };

            void M::f1(M m)
            {
            cout<<"A="< cout<<"B="< }

            int M::B=0;
            void main()
            {
            M P(5),Q(10);
            M::f1(P); file://調用時不用對象名
            M::f1(Q);
            }

              讀者可以自行分析其結果。從中可看出,調用靜態成員函數使用如下格式:
               <類名>::<靜態成員函數名>(<參數表>);

            posted on 2006-07-31 02:54 Jerry Cat 閱讀(292) 評論(0)  編輯 收藏 引用

            <2006年5月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            常用鏈接

            留言簿(7)

            隨筆檔案

            最新隨筆

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲精品美女久久久久99小说| 国产精品美女久久久网AV| 2020国产成人久久精品| 精品国产乱码久久久久久呢| 久久天天躁狠狠躁夜夜不卡| 国产成人久久精品激情 | 久久人妻少妇嫩草AV蜜桃| 久久久精品久久久久影院| 91久久精品91久久性色| 色悠久久久久久久综合网| 精品国产乱码久久久久久1区2区| 狠狠人妻久久久久久综合蜜桃| 老男人久久青草av高清| 777久久精品一区二区三区无码| 久久亚洲国产成人影院网站| 欧美大香线蕉线伊人久久| 久久亚洲天堂| 国产99久久九九精品无码| 午夜精品久久久久久久久| 亚洲国产精品综合久久一线| 久久se精品一区二区| 久久强奷乱码老熟女网站| 久久伊人五月天论坛| 一本色道久久88加勒比—综合| 久久婷婷成人综合色综合| 久久精品久久久久观看99水蜜桃| 久久久久久亚洲精品不卡| 久久天堂电影网| 久久久综合九色合综国产| 欧美丰满熟妇BBB久久久| 亚洲国产精品无码久久久不卡| 亚洲美日韩Av中文字幕无码久久久妻妇 | 久久婷婷五月综合色奶水99啪| 亚洲国产成人精品久久久国产成人一区二区三区综 | 国产色综合久久无码有码| 久久夜色tv网站| A级毛片无码久久精品免费| 久久人人爽人人爽人人片AV麻烦| 亚洲Av无码国产情品久久| 亚洲精品成人久久久| 久久久久久久久久久久久久|