柚子快報(bào)激活碼778899分享:C++ static詳解
柚子快報(bào)激活碼778899分享:C++ static詳解
參考:https://blog.csdn.net/u010797208/article/details/41549461
static詳解
static 作為關(guān)鍵字出現(xiàn)在C++語(yǔ)言當(dāng)中,其運(yùn)用比較復(fù)雜,其修飾全局變量,局部變量,類成員變量,類成員函數(shù)等都有不同釋義,下面為大家詳細(xì)描述一下.
一 static概述
static 從籠統(tǒng)意義的理解上,可以理解為 被此關(guān)鍵字修飾過(guò)的函數(shù)或變量,即為靜態(tài)函數(shù)或靜態(tài)變量. 靜態(tài)變量或函數(shù)式在系統(tǒng)編譯期,main函數(shù)運(yùn)行前就已經(jīng)分配內(nèi)存的.在聲明它的程序塊,子程序塊或函數(shù)內(nèi)部有效,值保持 雖然上面講了static關(guān)鍵字修飾不同的類型單位會(huì)有不同的效果,但其實(shí)可以理解為面向過(guò)程程序中的static和面向?qū)ο蟪绦蛑械膕tatic, 面向過(guò)程中的static主要適用于普通變量和函數(shù). 面向?qū)ο笾械膕tatic主要適用于類中的成員變量和成員函數(shù).
二 static用法詳解
面向過(guò)程中的static 靜態(tài)全局變量 在全局變量之前,加上關(guān)鍵字static,就可以定義該變量為靜態(tài)全局變量. 例:
#include
static int Temp = 10;
void Test();
int main()
{
printf("Temp is %d\n", Temp);//輸出:10
Test();//輸出:10
printf("Temp is %d\n", Temp);//輸出:11
return 0;
}
void Test()
{
Temp++;
}
局部變量之前加上static,可以指定該局部變量為靜態(tài)局部變量
代碼中主要有一下幾個(gè)特點(diǎn) 01.在全局?jǐn)?shù)據(jù)中的變量如果沒(méi)有顯示的初始化會(huì)自動(dòng)被程序初始化為0(這個(gè)特性非靜態(tài)全局變量也有),而在函數(shù)體內(nèi)聲明的變量如果不顯示初始化則會(huì)使一個(gè)隨機(jī)值. 02.靜態(tài)全局變量在聲明它的整個(gè)文件中都是課件的,而在文件之外是不可見的,這點(diǎn)區(qū)別于全局變量. 03.靜態(tài)全局變量在全局?jǐn)?shù)據(jù)區(qū)分配內(nèi)存 04.其他文件中可以定義同名int型變量Temp,不會(huì)沖突,各取各的值. 有一定C++語(yǔ)言功底的朋友可能看出,上面的示例代碼 其實(shí)如果將Temp的static去掉,程序也可以正常執(zhí)行.但是請(qǐng)注意以下區(qū)別. 01.全局變量時(shí)不顯示調(diào)用static關(guān)鍵字修飾的變量,全局變量默認(rèn)是有外部連接性的,其作用域是整個(gè)工程,在一個(gè)文件內(nèi)定義的全局變量可以通過(guò),包含其所在頭文件或顯示調(diào)用 extern關(guān)鍵字修飾全局變量的變量名聲明來(lái)引用. 02.靜態(tài)全局變量是顯示調(diào)用static修飾的全局變量,其作用域只在聲明此變量的文件中,其他文件即使使用extern關(guān)鍵字修飾其聲明也不可使用. 03.關(guān)于第二點(diǎn),其描述是C++標(biāo)準(zhǔn),但是有些編譯器會(huì)不執(zhí)行次標(biāo)準(zhǔn)特意對(duì)其進(jìn)行優(yōu)化,目前親測(cè)的vs2012與g++都不支持這個(gè)標(biāo)準(zhǔn)…個(gè)人表示也是醉了
靜態(tài)局部變量 在局部變量之前加上static,可以指定該局部變量為靜態(tài)局部變量
#include
void Test();
int main()
{
for(int i=0; i<5; i++)
{
Test();
}
return 0;
}
void Test()
{
static int Temp = 10;
printf("Temp is %d\n", Temp);
Temp++;
}
以上程序輸出為:
10 11 12 13 14 通常,在一個(gè)函數(shù)作用域內(nèi)定義一個(gè)變量,每次運(yùn)行到該函數(shù)時(shí),系統(tǒng)會(huì)給局部變量分配內(nèi)存,當(dāng)函數(shù)結(jié)束時(shí),該變量的內(nèi)存會(huì)被系統(tǒng)回收至棧內(nèi)存當(dāng)中,局部變量也會(huì)消散. 但是如果改局部變量被聲明為static 靜態(tài)局部變量時(shí),則該變量的生命周期不受到該函數(shù)的作用域限制,也就是說(shuō)即使函數(shù)運(yùn)行結(jié)束,系統(tǒng)仍然會(huì)保留該靜態(tài)變量的內(nèi)存,不會(huì)回收,它始終駐留在全局?jǐn)?shù)據(jù)區(qū)當(dāng)中,直到整個(gè)進(jìn)程程序運(yùn)行結(jié)束時(shí),其內(nèi)存才會(huì)被回收. 靜態(tài)局部變量有以下特點(diǎn): 01.其內(nèi)存存放在 程序的全局?jǐn)?shù)據(jù)區(qū)中, 02.靜態(tài)局部變量在程序執(zhí)行到該對(duì)象聲明時(shí),會(huì)被首次初始化.其后運(yùn)行到該對(duì)象的聲明時(shí),不會(huì)再次初始化,這也是為什么上面程序測(cè)試函數(shù)每次輸出的值都是遞增的原因. 03.如果靜態(tài)局部變量沒(méi)有被顯示初始化,則其值會(huì)自動(dòng)被系統(tǒng)初始化為0. 04.局部靜態(tài)變量 不能被其作用域之外的其他模塊調(diào)用,其調(diào)用范圍僅限于聲明該變量的函數(shù)作用域當(dāng)中. 靜態(tài)函數(shù) 在函數(shù)的返回類型前加上關(guān)鍵字static,可以將此函數(shù)聲明為靜態(tài)函數(shù).靜態(tài)函數(shù)與普通函數(shù)不同,其作用域只在聲明它的文件當(dāng)中.其他文件可以定義同名的全局函數(shù),而不沖突. 想要在其他文件調(diào)用靜態(tài)函數(shù) 需要顯示的調(diào)用extern關(guān)鍵字修飾其聲明.否則編譯器會(huì)link error.
#include
static void Test();
int main()
{
Test();
return 0;
}
void Test()
{
printf("Is Static Fun\n");
}
總結(jié)定義靜態(tài)函數(shù)的好處:
01.其他文件可以定義同名函數(shù) 02.靜態(tài)函數(shù)不會(huì)被其他文件所引用,其作用域只在當(dāng)前聲明他的文件中.
面向?qū)ο笾械膕tatic
靜態(tài)數(shù)據(jù)成員 在類內(nèi)的數(shù)據(jù)成員聲明前加上關(guān)鍵字static,則該成員將會(huì)被聲明為靜態(tài)數(shù)據(jù)成員.
#include
class TempClass
{
public:
TempClass(int a, int b, int c);
void Show();
private:
int a,b,c;
static int T;
};
int TempClass::T = 0;//初始化靜態(tài)數(shù)據(jù)成員
TempClass::TempClass(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
T = a + b + c;
}
void TempClass::Show()
{
printf("T is %d\n", T);
}
int main()
{
TempClass ClassA(1,1,1);
ClassA.Show();//輸出1+1+1 = 3;
TempClass ClassB(3,3,3);
ClassB.Show();//輸出3+3+3 = 9;
ClassA.Show();//輸出9
return 0;
}
從上面的測(cè)試代碼可以看出 靜態(tài)數(shù)據(jù)成員的特點(diǎn):
01.靜態(tài)數(shù)據(jù)成員的服務(wù)對(duì)象并非是單個(gè)類實(shí)例化的對(duì)象,而是所有類實(shí)例化的對(duì)象(這點(diǎn)可以用于設(shè)計(jì)模式中的單例模式實(shí)現(xiàn)). 02.靜態(tài)數(shù)據(jù)成員必須顯示的初始化分配內(nèi)存,在其包含類沒(méi)有任何實(shí)例花之前,其已經(jīng)有內(nèi)存分配. 03.靜態(tài)數(shù)據(jù)成員與其他成員一樣,遵從public,protected,private的訪問(wèn)規(guī)則. 04.靜態(tài)數(shù)據(jù)成員內(nèi)存存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),只隨著進(jìn)程的消亡而消亡.
靜態(tài)數(shù)據(jù)成員與全局變量相比的優(yōu)勢(shì): 01.靜態(tài)數(shù)據(jù)成員不進(jìn)入程序全局名字空間,不會(huì)與其他全局名稱的同名同類型變量沖突. 02.靜態(tài)數(shù)據(jù)成員可以實(shí)現(xiàn)C++的封裝特性,由于其遵守類的訪問(wèn)權(quán)限規(guī)則.所以相比全局變量更加靈活.
靜態(tài)成員函數(shù) 在類的成員函數(shù)返回類型之前添加static,即可聲明此成員函數(shù)為靜態(tài)成員函數(shù).
#include
class TempClass
{
public:
TempClass(int a, int b, int c);
static void Show();
private:
int a,b,c;
static int T;
};
int TempClass::T = 0; //初始化靜態(tài)數(shù)據(jù)成員
TempClass::TempClass(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
T = a + b + c;
}
void TempClass::Show()
{
printf("T is %d\n", T);
}
int main()
{
TempClass ClassA(1,1,1);
ClassA.Show();
TempClass ClassB(3,3,3);
ClassB.Show();
TempClass::Show(); //注意此處的調(diào)用方式.
return 0;
}
從上面的示例代碼中可以看出 靜態(tài)局部函數(shù)的特點(diǎn)如下:
01.靜態(tài)成員函數(shù)比普通成員函數(shù)多了一種調(diào)用方式. 02.靜態(tài)成員函數(shù)為整個(gè)類服務(wù),而不是具體的一個(gè)類的實(shí)例服務(wù).(這句話可能比較繞口,可以理解為在沒(méi)有任何實(shí)例化的類對(duì)象的條件下調(diào)用類方法,詳見上面代碼注釋處.) 03.靜態(tài)成員函數(shù)中沒(méi)有隱含的this指針,所以靜態(tài)成員函數(shù)不可以操作類中的非靜態(tài)成員.
ps:關(guān)于this指針的深入解釋 在C++中,普通的成員函數(shù)一般都隱含了一個(gè)this指針,例如調(diào)用函數(shù)Fun(),實(shí)際上是this->Fun(). 靜態(tài)成員函數(shù)中沒(méi)有這樣的this指針,所以靜態(tài)成員函數(shù)不能操作類中的非靜態(tài)成員函數(shù).否則編譯器會(huì)報(bào)錯(cuò).
三 注意事項(xiàng)
01.靜態(tài)數(shù)據(jù)成員都是靜態(tài)存儲(chǔ)的,所以必須在main函數(shù)之前顯示的對(duì)其進(jìn)行初始化. 02.靜態(tài)成員初始化與一般成員的初始化不同. 03.不能再頭文件中聲明靜態(tài)全局變量,這點(diǎn)在簡(jiǎn)單的測(cè)試代碼中無(wú)法體現(xiàn),只有在多文件同時(shí)包含,引用和操作時(shí)候才會(huì)顯露出來(lái).其結(jié)果可能是產(chǎn)生了多個(gè)同名的靜態(tài)數(shù)據(jù).一旦出現(xiàn)這種問(wèn)題,是非常難以查找和排除的. 04.不能將靜態(tài)成員函數(shù)定義為虛函數(shù). 05.靜態(tài)成員函數(shù)沒(méi)有this指針. 06.static縮短了子類對(duì)父類靜態(tài)成員訪問(wèn)的時(shí)間,相對(duì)來(lái)說(shuō)節(jié)省了內(nèi)存空間 07.關(guān)于06條的補(bǔ)充,如果不想在子類中操作父類的靜態(tài)成員,則可以在子類中定義一個(gè)同名的static成員.這樣既可覆蓋父類中的靜態(tài)成員.并且根據(jù)C++的多態(tài)性變量命名規(guī)則.這樣做是安全的. 08.靜態(tài)成員聲明在類中,操作在其外部,所以對(duì)其取地址操作就跟取普通成員的操作略有不同.靜態(tài)變量地址是指向其數(shù)據(jù)類型的指針,函數(shù)地址則是一個(gè)類型為nonmember的函數(shù)指針.
柚子快報(bào)激活碼778899分享:C++ static詳解
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。