• <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>
            posts - 297,  comments - 15,  trackbacks - 0

            C++static有兩種用法:面向過程程序設計中的static和面向對象程序設計中的static。前者應用于普通變量和函數,不涉及類;后者主要說明static在類中的作用。

            一、面向過程設計中的static

            1、靜態全局變量

            在全局變量前,加上關鍵字static,該變量就被定義成為一個靜態全局變量。我們先舉一個靜態全局變量的例子,如下:

            //Example 1

            #include <iostream.h>

            void fn();

            static int n; //定義靜態全局變量

            void main()

            {

                n = 20;

                cout<< n <<endl;

                fn();

            }

             

            void fn()

            {

                n++;

                cout<< n <<endl;

            }

            靜態全局變量有以下特點:

            ·       該變量在全局數據區分配內存;

            ·       未經初始化的靜態全局變量會被程序自動初始化為0(自動變量的值是隨機的,除非它被顯式初始化);

            ·       靜態全局變量在聲明它的整個文件都是可見的,而在文件之外是不可見的; 

            靜態變量都在全局數據區分配內存,包括后面將要提到的靜態局部變量。對于一個完整的程序,在內存中的分布情況如下圖:

            代碼區

            全局數據區

            堆區

            棧區

            一般程序的由new產生的動態數據存放在堆區,函數內部的自動變量存放在棧區。自動變量一般會隨著函數的退出而釋放空間,靜態數據(即使是函數內部的靜態局部變量)也存放在全局數據區。全局數據區的數據并不會因為函數的退出而釋放空間。細心的讀者可能會發現,Example 1中的代碼中將

            static int n; //定義靜態全局變量

            改為

            int n; //定義全局變量

            程序照樣正常運行。

            的確,定義全局變量就可以實現變量在文件中的共享,但定義靜態全局變量還有以下好處:

            ·       靜態全局變量不能被其它文件所用;

            ·       其它文件中可以定義相同名字的變量,不會發生沖突;

            您可以將上述示例代碼改為如下:

            //Example 2

            //File1

            #include <iostream.h>

            void fn();

            static int n; //定義靜態全局變量

            void main()

            {

                n=20;

                cout<<n<<endl;

                fn();

            }

             

            //File2

            #include <iostream.h>

            extern int n;

            void fn()

            {

                n++;

                cout<<n<<endl;

            }

            編譯并運行Example 2,您就會發現上述代碼可以分別通過編譯,但運行時出現錯誤。 試著將

            static int n; //定義靜態全局變量

            改為

            int n; //定義全局變量

            再次編譯運行程序,細心體會全局變量和靜態全局變量的區別(驗證共享和保護關系)

             

            2、靜態局部變量

            在局部變量前,加上關鍵字static,該變量就被定義成為一個靜態局部變量。

            我們先舉一個靜態局部變量的例子,如下:

            //Example 3

            #include <iostream.h>

            void fn();

            void main()

            {

                fn();

                fn();

                fn();

            }

             

            void fn()

            {

                static n=10;

                cout<<n<<endl;

                n++;

            }

            通常,在函數體內定義了一個變量,每當程序運行到該語句時都會給該局部變量分配棧內存。但隨著程序退出函數體,系統就會收回棧內存,局部變量也相應失效。

            但有時候我們需要在兩次調用之間對變量的值進行保存。通常的想法是定義一個全局變量來實現。但這樣一來,變量已經不再屬于函數本身了,不再僅受函數的控制,給程序的維護帶來不便。

            靜態局部變量正好可以解決這個問題。靜態局部變量保存在全局數據區,而不是保存在棧中,每次的值保持到下一次調用,直到下次賦新值。

            靜態局部變量有以下特點:

            ·       該變量在全局數據區分配內存;

            ·       靜態局部變量在程序執行到該對象的聲明處時被首次初始化,即以后的函數調用不再進行初始化;

            ·       靜態局部變量一般在聲明處初始化,如果沒有顯式初始化,會被程序自動初始化為0

            ·       它始終駐留在全局數據區,直到程序運行結束。但其作用域為局部作用域,當定義它的函數或語句塊結束時,其作用域隨之結束

             

            3、靜態函數

            在函數的返回類型前加上static關鍵字,函數即被定義為靜態函數。靜態函數與普通函數不同,它只能在聲明它的文件當中可見,不能被其它文件使用。

            靜態函數的例子:

            //Example 4

            #include <iostream.h>

            static void fn();//聲明靜態函數

            void main()

            {

                fn();

            }

             

            void fn()//定義靜態函數

            {

                int n=10;

                cout<<n<<endl;

            }

            定義靜態函數的好處:

            ·       靜態函數不能被其它文件所用;

            ·       其它文件中可以定義相同名字的函數,不會發生沖突

             

            二、面向對象的static關鍵字(類中的static關鍵字)

            1、靜態數據成員

            在類內數據成員的聲明前加上關鍵字static,該數據成員就是類內的靜態數據成員。先舉一個靜態數據成員的例子。

            //Example 5

            #include <iostream.h>

            class Myclass

            {

            public:

                Myclass(int a,int b,int c);

                void GetSum();

            private:

                int a,b,c;

                static int Sum;//聲明靜態數據成員

            };

            //以下部分不能出現在頭文件中

            int Myclass::Sum = 0;//定義并初始化靜態數據成員

             

            Myclass::Myclass(int a,int b,int c)

            {

                this->a=a;

                this->b=b;

                this->c=c;

                Sum+=a+b+c;

            }

             

            void Myclass::GetSum()

            {

                cout<<"Sum="<<Sum<<endl;

            }

             

            void main()

            {

                Myclass M(1,2,3);

                M.GetSum();     //Sum = 6

                Myclass N(4,5,6);

                N.GetSum();     //Sum = 21

                M.GetSum();     //Sum = 21

            }

            可以看出,靜態數據成員有以下特點:

            ·       對于非靜態數據成員,每個類對象都有自己的拷貝。而靜態數據成員被當作是類的成員。無論這個類的對象被定義了多少個,靜態數據成員在程序中也只有一份拷貝,由該類型的所有對象共享訪問。也就是說,靜態數據成員是該類的所有對象所共有的。對該類的多個對象來說,靜態數據成員只分配一次內存,供所有對象共用。所以,靜態數據成員的值對每個對象都是一樣的,它的值可以更新

            ·       靜態數據成員存儲在全局數據區。靜態數據成員定義時要分配空間,所以不能在類聲明中定義。在Example 5中,語句int Myclass::Sum=0;是定義靜態數據成員;

            ·       靜態數據成員和普通數據成員一樣遵從public,protected,private訪問規則;

            ·       因為靜態數據成員在全局數據區分配內存,屬于本類的所有對象共享,所以,它不屬于特定的類對象,在沒有產生類對象時其作用域就可見,即在沒有產生類的實例時,我們就可以操作它

            ·       靜態數據成員初始化與一般數據成員初始化不同。靜態數據成員初始化的格式為:<數據類型><類名>::<靜態數據成員名>=<值>

            ·       類的靜態數據成員有兩種訪問形式:<類對象名>.<靜態數據成員名> 或<類類型名>::<靜態數據成員名>如果靜態數據成員的訪問權限允許的話(即public的成員),可在程序中,按上述格式來引用靜態數據成員;

            ·       靜 態數據成員主要用在各個對象都有相同的某項屬性的時候。比如對于一個存款類,每個實例的利息都是相同的。所以,應該把利息設為存款類的靜態數據成員。這有 兩個好處,第一,不管定義多少個存款類對象,利息數據成員都共享分配在全局數據區的內存,所以節省存儲空間。第二,一旦利息需要改變時,只要改變一次,則 所有存款類對象的利息全改變過來了;

            ·       同全局變量相比,使用靜態數據成員有兩個優勢:

            1.   靜態數據成員沒有進入程序的全局名字空間,因此不存在與程序中其它全局名字沖突的可能性;

            2.   可以實現信息隱藏。靜態數據成員可以是private成員,而全局變量不能

             

            2、靜態成員函數

            與靜態數據成員一樣,我們也可以創建一個靜態成員函數,它為類的全部服務而不是為某一個類的具體對象服務。靜態成員函數與靜態數據成員一樣,都是類的內部實現,屬于類定義的一部分。普通的成員函數一般都隱含了一個this指針,this指針指向類的對象本身,因為普通成員函數總是具體的屬于某個類的具體對象的。通常情況下,this是缺省的。如函數fn()實際上是this->fn()。但是與普通函數相比,靜態成員函數由于不是與任何的對象相聯系,因此它不具有this指針。從這個意義上講,它無法訪問屬于類對象的非靜態數據成員,也無法訪問非靜態成員函數,它只能調用其余的靜態成員函數。 下面舉個靜態成員函數的例子。

            //Example 6

            #include <iostream.h>

            class Myclass

            {

            public:

                Myclass(int a,int b,int c);

                static void GetSum();//聲明靜態成員函數

            private:

                int a,b,c;

                static int Sum;//聲明靜態數據成員

            };

             

            //以下必須在實現文件中

            int Myclass::Sum=0;//定義并初始化靜態數據成員

             

            Myclass::Myclass(int a,int b,int c)

            {

                this->a=a;

                this->b=b;

                this->c=c;

                Sum+=a+b+c; //非靜態成員函數可以訪問靜態數據成員

            }

             

            void Myclass::GetSum() //靜態成員函數的實現

            {

            //  cout<<a<<endl; //錯誤代碼,a是非靜態數據成員

                cout<<"Sum="<<Sum<<endl;

            }

             

            void main()

            {

                Myclass M(1,2,3);

                M.GetSum();

                Myclass N(4,5,6);

                N.GetSum();

                Myclass::GetSum();

            }

            關于靜態成員函數,可以總結為以下幾點:

            ·       出現在類體外的函數定義不能指定關鍵字static

            ·       靜態成員之間可以相互訪問,包括靜態成員函數訪問靜態數據成員和訪問靜態成員函數;

            ·       非靜態成員函數可以任意地訪問靜態成員函數和靜態數據成員;

            ·       靜態成員函數不能訪問非靜態成員函數和非靜態數據成員;

            ·       由于沒有this指針的額外開銷,因此靜態成員函數與類的全局函數相比速度上會有少許的增長;

            ·       調用靜態成員函數,可以用成員訪問操作符(.)(->)為一個類的對象或指向類對象的指針調用靜態成員函數,也可以直接使用如下格式:<類名>::<靜態成員函數名>(<參數表>)調用類的靜態成員函數。

             

            另:VC6VC7.1static支持的差異

            class CStaic

            {

            public:

                CStatic()

                {

                }

             

                ~CStatic()

                {

                }

             

            private:

                static const int DefaultBufferSize = 1024;

            };

             

            上面的寫法在VC++ .net 7.1能夠編譯通過,但是在VC6上不支持,會出現編譯錯誤。

            需要改成下面的寫法。

            class CStaic

            {

            public:

                CStatic()

                {

                }

             

                ~CStatic()

                {

                }

             

            private:

                static const int DefaultBufferSize;

            };

             

            const int CStaic::DefaultBufferSize = 1024;
            posted on 2008-07-19 00:56 chatler 閱讀(273) 評論(0)  編輯 收藏 引用 所屬分類: C++_BASIS
            <2009年5月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品免费大片国产大片 | 国产精品欧美久久久天天影视| 狠狠色婷婷久久一区二区 | 国产综合久久久久| 99久久精品免费看国产一区二区三区| 武侠古典久久婷婷狼人伊人| 久久精品国产第一区二区三区| 久久国产精品免费| 久久亚洲精品人成综合网| 久久一区二区三区免费| 2021少妇久久久久久久久久| 超级碰碰碰碰97久久久久| 久久精品国内一区二区三区| 久久久久亚洲av成人网人人软件| 久久中文娱乐网| 久久A级毛片免费观看| 超级97碰碰碰碰久久久久最新 | 久久久精品久久久久影院| 伊人久久大香线蕉精品| 午夜精品久久久久久毛片| 国内精品伊人久久久久妇| A级毛片无码久久精品免费| AV无码久久久久不卡蜜桃| 久久久久久精品久久久久| 欧美日韩精品久久久久| 日本一区精品久久久久影院| 久久亚洲中文字幕精品有坂深雪| 狠狠色狠狠色综合久久| 狠狠色丁香婷婷久久综合| 免费一级做a爰片久久毛片潮| 久久精品九九亚洲精品天堂| 精品人妻久久久久久888| 色偷偷偷久久伊人大杳蕉| 久久久久久久女国产乱让韩| 色播久久人人爽人人爽人人片AV | 国产99精品久久| 97久久国产亚洲精品超碰热| 成人国内精品久久久久影院| 久久国产免费观看精品| 久久国产精品成人免费| 精品久久久久久国产免费了|