静态成员变量和静态成员函数(static)
數(shù)據(jù)成員可以分靜態(tài)變量、非靜態(tài)變量兩種.
靜態(tài)成員:靜態(tài)類中的成員加入static修飾符,即是靜態(tài)成員.可以直接使用類名+靜態(tài)成員名訪問此靜態(tài)成員,因?yàn)殪o態(tài)成員存在于內(nèi)存,非靜態(tài)成員需要實(shí)例化才會分配內(nèi)存,所以靜態(tài)成員不能訪問非靜態(tài)的成員..因?yàn)殪o態(tài)成員存在于內(nèi)存,所以非靜態(tài)成員可以直接訪問類中靜態(tài)的成員.
非成靜態(tài)員:所有沒有加Static的成員都是非靜態(tài)成員,當(dāng)類被實(shí)例化之后,可以通過實(shí)例化的類名進(jìn)行訪問..非靜態(tài)成員的生存期決定于該類的生存期..而靜態(tài)成員則不存在生存期的概念,因?yàn)殪o態(tài)成員始終駐留在內(nèi)容中..
一個類中也可以包含靜態(tài)成員和非靜態(tài)成員,類中也包括靜態(tài)構(gòu)造函數(shù)和非靜態(tài)構(gòu)造函數(shù)..
分兩個方面來總結(jié),第一方面主要是相對于面向過程而言,即在這方面不涉及到類,第二方面相對于面向?qū)ο蠖?#xff0c;主要說明static在類中的作用。
一、在面向過程設(shè)計(jì)中的static關(guān)鍵字
1、靜態(tài)全局變量
定義:在全局變量前,加上關(guān)鍵字 static 該變量就被定義成為了一個靜態(tài)全局變量。
特點(diǎn):
A、該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存。
B、初始化:如果不顯式初始化,那么將被隱式初始化為0(自動變量是隨機(jī)的,除非顯式地初始化)。
C、訪變量只在本源文件可見,嚴(yán)格的講應(yīng)該為定義之處開始到本文件結(jié)束。
例(摘于C++程序設(shè)計(jì)教程---錢能主編P103): //file1.cpp
//Example 1
??????????????????????????? #include <iostream.h>
??????????????????????????? void fn();
???????????????????????????? static int n; //定義靜態(tài)全局變量
???????????????????????????? void main()
???????????????????????????? {
??????????????? n=20;
??????????????? cout<<n<<endl;
??????????????? fn();
???????????????????????????? }
????????????????????????????? void fn()
????????????????????????????? {
??????????????? n++;
??????????????? cout<<n<<endl;
????????????????????????????? }
D、文件作用域下聲明的const的常量默認(rèn)為static存儲類型。
靜態(tài)變量都在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存,包括后面將要提到的靜態(tài)局部變量。對于一個完整的程序,在內(nèi)存中的分布情況如下圖:
代碼區(qū)全局?jǐn)?shù)據(jù)區(qū)堆區(qū)棧區(qū)
一般程序的由new產(chǎn)生的動態(tài)數(shù)據(jù)存放在堆區(qū),函數(shù)內(nèi)部的自動變量存放在棧區(qū)。自動變量一般會隨著函數(shù)的退出而釋放空間,靜態(tài)數(shù)據(jù)(即使是函數(shù)內(nèi)部的靜態(tài)局部變量)也存放在全局?jǐn)?shù)據(jù)區(qū)。全局?jǐn)?shù)據(jù)區(qū)的數(shù)據(jù)并不會因?yàn)楹瘮?shù)的退出而釋放空間。細(xì)心的讀者可能會發(fā)現(xiàn),Example 1中的代碼中將
???????????????? static int n; //定義靜態(tài)全局變量
改為:
int n; //定義全局變量
程序照樣正常運(yùn)行。的確,定義全局變量就可以實(shí)現(xiàn)變量在文件中的共享,但定義靜態(tài)全局變量還有以下好處:
靜態(tài)全局變量不能被其它文件所用;(好像是區(qū)別extern的) 其它文件中可以定義相同名字的變量,不會發(fā)生沖突; 您可以將上述示例代碼改為如下: //Example 2//File1#include <iostream.h>void fn();static int n; //定義靜態(tài)全局變量(只能在本文件中使用)void main(){ n=20; cout<<n<<endl; fn();}//File2#include <iostream.h>extern int n;(可在別的文件中引用這個變量)void fn(){ n++; cout<<n<<endl;}
編譯并運(yùn)行Example 2,您就會發(fā)現(xiàn)上述代碼可以分別通過編譯,但link時出現(xiàn)錯誤。試著將 static int n; //定義靜態(tài)全局變量
改為int n; //定義全局變量
再次編譯運(yùn)行程序,細(xì)心體會全局變量和靜態(tài)全局變量的區(qū)別。
2、靜態(tài)局部變量
定義:在局部變量前加上static關(guān)鍵字時,就定義了靜態(tài)局部變量。
我們先舉一個靜態(tài)局部變量的例子,如下:
//Example 3#include <iostream.h>void fn();void main(){ fn(); fn(); fn();}void fn(){ static n=10; cout<<n<<endl; n++;}
通常,在函數(shù)體內(nèi)定義了一個變量,每當(dāng)程序運(yùn)行到該語句時都會給該局部變量分配棧內(nèi)存。但隨著程序退出函數(shù)體,系統(tǒng)就會收回棧內(nèi)存,局部變量也相應(yīng)失效。
但有時候我們需要在兩次調(diào)用之間對變量的值進(jìn)行保存。通常的想法是定義一個全局變量來實(shí)現(xiàn)。但這樣一來,變量已經(jīng)不再屬于函數(shù)本身了,不再僅受函數(shù)的控制,給程序的維護(hù)帶來不便。
靜態(tài)局部變量正好可以解決這個問題。靜態(tài)局部變量保存在全局?jǐn)?shù)據(jù)區(qū),而不是保存在棧中,每次的值保持到下一次調(diào)用,直到下次賦新值。
特點(diǎn):
A、該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存。
B、初始化:如果不顯式初始化,那么將被隱式初始化為0,以后的函數(shù)調(diào)用不再進(jìn)行初始化。
C、它始終駐留在全局?jǐn)?shù)據(jù)區(qū),直到程序運(yùn)行結(jié)束。但其作用域?yàn)榫植孔饔糜?#xff0c;當(dāng)定義它的函數(shù)或 語句塊結(jié)束時,其作用域隨之結(jié)束。
3、靜態(tài)函數(shù)(注意與類的靜態(tài)成員函數(shù)區(qū)別)
定義:在函數(shù)的返回類型前加上static關(guān)鍵字,函數(shù)即被定義成靜態(tài)函數(shù)。
特點(diǎn):
A、靜態(tài)函數(shù)與普通函數(shù)不同,它只能在聲明它的文件當(dāng)中可見,不能被其它文件使用。
靜態(tài)函數(shù)的例子:
//Example 4#include <iostream.h>static void fn();//聲明靜態(tài)函數(shù)void main(){ fn();}void fn()//定義靜態(tài)函數(shù){ int n=10; cout<<n<<endl;}
定義靜態(tài)函數(shù)的好處:
靜態(tài)函數(shù)不能被其它文件所用; 其它文件中可以定義相同名字的函數(shù),不會發(fā)生沖突; 二、面向?qū)ο蟮膕tatic關(guān)鍵字(類中的static關(guān)鍵字) 1、靜態(tài)數(shù)據(jù)成員
在類內(nèi)數(shù)據(jù)成員的聲明前加上關(guān)鍵字static,該數(shù)據(jù)成員就是類內(nèi)的靜態(tài)數(shù)據(jù)成員。先舉一個靜態(tài)數(shù)據(jù)成員的例子。
//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;//聲明靜態(tài)數(shù)據(jù)成員
};
int Myclass::Sum=0;//定義并初始化靜態(tài)數(shù)據(jù)成員
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<<"SSum="<<Sum<<endl;
}
void main()
{
Myclass M(1,2,3);
M.GetSum();
Myclass N(4,5,6);
N.GetSum();
Myclass::GetSum();
}
關(guān)于靜態(tài)成員函數(shù),可以總結(jié)為以下幾點(diǎn):
出現(xiàn)在類體外的函數(shù)定義不能指定關(guān)鍵字static; 靜態(tài)成員之間可以相互訪問,包括靜態(tài)成員函數(shù)訪問靜態(tài)數(shù)據(jù)成員和訪問靜態(tài)成員函數(shù); 非靜態(tài)成員函數(shù)可以任意地訪問靜態(tài)成員函數(shù)和靜態(tài)數(shù)據(jù)成員; 靜態(tài)成員函數(shù)不能訪問非靜態(tài)成員函數(shù)和非靜態(tài)數(shù)據(jù)成員; 由于沒有this指針的額外開銷,因此靜態(tài)成員函數(shù)與類的全局函數(shù)相比速度上會有少許的增長; 調(diào)用靜態(tài)成員函數(shù),可以用成員訪問操作符(.)和(->)為一個類的對象或指向類對象的指針調(diào)用靜態(tài)成員函數(shù),也可以直接使用如下格式: <類名>::<靜態(tài)成員函數(shù)名>(<參數(shù)表>)
調(diào)用類的靜態(tài)成員函數(shù)。
轉(zhuǎn)載于:https://www.cnblogs.com/Shadowing/p/3422463.html
總結(jié)
以上是生活随笔為你收集整理的静态成员变量和静态成员函数(static)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: script的defer和async
- 下一篇: NS 802.11函数分析(一)