static關(guān)鍵字的用法
static 是c++中很常用的修飾符,它被用來(lái)控制變量的存儲(chǔ)方式和可見(jiàn)性,下面我將從 static 修飾符的產(chǎn)生原因、作用談起,全面分析static 修飾符的實(shí)質(zhì)。
static 的兩大作用:
一、控制存儲(chǔ)方式:static被引入以告知編譯器,將變量存儲(chǔ)在程序的靜態(tài)存儲(chǔ)區(qū)而非棧上空間。1、引出原因:函數(shù)內(nèi)部定義的變量,在程序執(zhí)行到它的定義處時(shí),編譯器為它在棧上分配空間,大家知道,函數(shù)在棧上分配的空間在此函數(shù)執(zhí)行結(jié)束時(shí)會(huì)釋放掉,這樣就產(chǎn)生了一個(gè)問(wèn)題: 如果想將函數(shù)中此變量的值保存至下一次調(diào)用時(shí),如何實(shí)現(xiàn)?最容易想到的方法是定義一個(gè)全局的變量,但定義為一個(gè)全局變量有許多缺點(diǎn),最明顯的缺點(diǎn)是破壞了此變量的訪問(wèn)范圍(使得在此函數(shù)中定義的變量,不僅僅受此函數(shù)控制)。2、 解決方案:因此c++ 中引入了static,用它來(lái)修飾變量,它能夠指示編譯器將此變量在程序的靜態(tài)存儲(chǔ)區(qū)分配空間保存,這樣即實(shí)現(xiàn)了目的,又使得此變量的存取范圍不變。
二、控制可見(jiàn)性與連接類型 :static還有一個(gè)作用,它會(huì)把變量的可見(jiàn)范圍限制在編譯單元中,使它成為一個(gè)內(nèi)部連接,這時(shí),它的反義詞為”extern”.static作用分析總結(jié):static總是使得變量或?qū)ο蟮拇鎯?chǔ)形式變成靜態(tài)存儲(chǔ),連接方式變成內(nèi)部連接,對(duì)于局部變量(已經(jīng)是內(nèi)部連接了),它僅改變其存儲(chǔ)方式;對(duì)于全局變量(已經(jīng)是靜態(tài)存儲(chǔ)了),它僅改變其連接類型。
類中的static成員:
一、出現(xiàn)原因及作用:
1、需要在一個(gè)類的各個(gè)對(duì)象間交互,即需要一個(gè)數(shù)據(jù)對(duì)象為整個(gè)類而非某個(gè)對(duì)象服務(wù)。
2、同時(shí)又力求不破壞類的封裝性,即要求此成員隱藏在類的內(nèi)部,對(duì)外不可見(jiàn)。
類的static成員滿足了上述的要求,因?yàn)樗哂腥缦绿卣鳎河歇?dú)立的存儲(chǔ)區(qū),屬于整個(gè)類。
二、注意:
1、對(duì)于靜態(tài)的數(shù)據(jù)成員,連接器會(huì)保證它擁有一個(gè)單一的外部定義。靜態(tài)數(shù)據(jù)成員按定義出現(xiàn)的先后順序依次初始化,注意靜態(tài)成員嵌套時(shí),要保證所嵌套的成員已經(jīng)初始化了。消除時(shí)的順序是初始化的反順序。
2、類的靜態(tài)成員函數(shù)是屬于整個(gè)類而非類的對(duì)象,所以它沒(méi)有this指針,這就導(dǎo)致了它僅能訪問(wèn)類的靜態(tài)數(shù)據(jù)和靜態(tài)成員函數(shù)。
如下是對(duì)靜態(tài)關(guān)鍵字的一些說(shuō)明。
1、靜態(tài)全局變量
定義:在全局變量前,加上關(guān)鍵字 static 該變量就被定義成為了一個(gè)靜態(tài)全局變量。
特點(diǎn):
A、該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存。
B、初始化:如果不顯式初始化,那么將被隱式初始化為0。
C、訪變量只在本源文件可見(jiàn),嚴(yán)格的講應(yīng)該為定義之處開(kāi)始到本文件結(jié)束。
例(摘于C++程序設(shè)計(jì)教程---錢能主編P103):
//file1.cpp
#include<iostream.h>
void fn();
extern int n;
void main()
{
n=20;
cout << n << endl;
fn();
}
//file2.cpp
#include<iostream.h>
static int n; //定義靜態(tài)全局變量,初始化為0;
void fn()
{
n++;
cout << n << endl;
}
文件分別編譯能通過(guò),但連接時(shí)file1.cpp 中的變量n找不到定義,產(chǎn)生連接錯(cuò)誤。
D、文件作用域下聲明的const的常量默認(rèn)為static存儲(chǔ)類型。
2、靜態(tài)局部變量
定義:在局部變量前加上static關(guān)鍵字時(shí),就定義了靜態(tài)局部變量。
特點(diǎn):
A、該變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存。
B、初始化:如果不顯式初始化,那么將被隱式初始化為0。
C、它始終駐留在全局?jǐn)?shù)據(jù)區(qū),直到程序運(yùn)行結(jié)束。但其作用域?yàn)榫植孔饔糜颍?dāng)定義它的函數(shù)或 語(yǔ)句塊結(jié)束時(shí),其作用域隨之結(jié)束。
3、靜態(tài)函數(shù)(注意與類的靜態(tài)成員函數(shù)區(qū)別)
定義:在函數(shù)的返回類型前加上static關(guān)鍵字,函數(shù)即被定義成靜態(tài)函數(shù)。
特點(diǎn):
A、靜態(tài)函數(shù)只能在本源文件中使用(這是與普通函數(shù)區(qū)別)
例(摘于C++程序設(shè)計(jì)教程---錢能主編P103):
//file1.cpp
void fn();
void staticFn()
void main()
{
fn();
staticFn();
}
//file2.cpp
#include<iostream.h>
static void staticFn();
void fn();
void fn()
{
staticFn();
cout << "this is fn() \n";
}
void staticFn()
{
cout << "this is staticFn() \n";
}
連接時(shí),將產(chǎn)生找不到函數(shù)staticFn()定義的錯(cuò)誤。
B、主意事項(xiàng)
在文件作用域下聲明的inline函數(shù)默認(rèn)為static類型。
二、面象對(duì)象中的static關(guān)鍵字(主要指類中的static關(guān)鍵字)
1、靜態(tài)數(shù)據(jù)成員
特點(diǎn):
A、內(nèi)存分配:在程序的全局?jǐn)?shù)據(jù)區(qū)分配。
B、初始化和定義:
a、靜態(tài)數(shù)據(jù)成員定義時(shí)要分配空間,所以不能在類聲明中定義。
b、為了避免在多個(gè)使用該類的源文件中,對(duì)其重復(fù)定義,所在,不能在類的頭文件中定義。
c、靜態(tài)數(shù)據(jù)成員因?yàn)槌绦蛞婚_(kāi)始運(yùn)行就必需存在,所以其初始化的最佳位置在類的內(nèi)部實(shí)現(xiàn)。
C、特點(diǎn)
a、對(duì)相于 public,protected,private 關(guān)鍵字的影響它和普通數(shù)據(jù)成員一樣,
b、因?yàn)槠淇臻g在全局?jǐn)?shù)據(jù)區(qū)分配,屬于所有本類的對(duì)象共享,所以,它不屬于特定的類對(duì)象,在沒(méi)產(chǎn)生類對(duì)象時(shí)其作用域就可見(jiàn),即在沒(méi)有產(chǎn)生類的實(shí)例時(shí),我們就可以操作它。
D、訪問(wèn)形式
a、 類對(duì)象名.靜態(tài)數(shù)據(jù)成員名
b、 類類型名:: 靜態(tài)數(shù)據(jù)成員名
E、靜態(tài)數(shù)據(jù)成員,主要用在類的所有實(shí)例都擁有的屬性上。比如,對(duì)于一個(gè)存款類,帳號(hào)相對(duì) 于每個(gè)實(shí)例都是不同的,但每個(gè)實(shí)例的利息是相同的。所 以,應(yīng)該把利息設(shè)為存款類的靜態(tài)數(shù)據(jù)成員。這有兩個(gè)好處,第一,不管定義多少個(gè)存款類對(duì)象,利息數(shù)據(jù)成員都共享分配在全局區(qū)的內(nèi)存,所以節(jié)省存貯空間。第 二,一旦利息需要改變時(shí),只要改變一次,則所有存款類對(duì)象的利息全改變過(guò)來(lái)了,因?yàn)樗鼈儗?shí)際上是共用一個(gè)東西。
2、靜態(tài)成員函數(shù)
特點(diǎn):
A、靜態(tài)成員函數(shù)與類相聯(lián)系,不與類的對(duì)象相聯(lián)系。
B、靜態(tài)成員函數(shù)不能訪問(wèn)非靜態(tài)數(shù)據(jù)成員。原因很簡(jiǎn)單,非靜態(tài)數(shù)據(jù)成員屬于特定的類實(shí)例。
作用:
主要用于對(duì)靜態(tài)數(shù)據(jù)成員的操作。
調(diào)用形式:
A、類對(duì)象名.靜態(tài)成員函數(shù)名()
B、類類型名:: 靜態(tài)成員函數(shù)名()