C++ static的作用解讀
1. 隱藏
當(dāng)同時(shí)編譯多個(gè)文件時(shí),所有未加 static 前綴的全局變量和函數(shù)都具有全局可見性。
下面是一個(gè)簡(jiǎn)單的例子:
假設(shè)我們要編譯兩個(gè)文件 a.c 和 main.c
// a.c char a = 'A'; void msg() { ? ? printf("Hello\n"); }
//main.c int main(void) { ?? ?extern char a; ?? ?print(“%c ”, a); ?? ?(void)msg(); ?? ?return 0; }
此時(shí)程序運(yùn)行的結(jié)果是:
A Hello
而如果在 a 和 msg 定義前加了 static,那么 main.c 就無(wú)法使用它們了。利用這一特性可以避免命名沖突。
對(duì)于函數(shù)來(lái)說(shuō),static 的作用僅限于隱藏。而對(duì)于變量來(lái)說(shuō),它還有其他作用。
2. 保持變量?jī)?nèi)容的持久
儲(chǔ)存在靜態(tài)數(shù)據(jù)區(qū)的變量會(huì)在程序剛開始運(yùn)行時(shí)完成它唯一的一次初始化,它與全局變量一起儲(chǔ)存在靜態(tài)存儲(chǔ)區(qū),只不過(guò) static 的作用域不一定是全局的。
說(shuō)到底,這其實(shí)也可以理解為一種隱藏。
int func(void) { ?? ?static int count = 10; //僅在初始化時(shí)被執(zhí)行了一次,靜態(tài)變量只會(huì)進(jìn)行一次初始化 ?? ?return count—-; } int count = 1; int main(void) { ?? ?printf(“global\t\tlocal static\n”); ?? ?for (; count<=10; count++) ?? ?{ ?? ??? ?printf(“%d\t\t%d\n”, count, func()); ?? ?} ?? ?return 0; }
3. 默認(rèn)初始化為 0
全局變量也有這一特點(diǎn),因?yàn)樗泊鎯?chǔ)在靜態(tài)數(shù)據(jù)區(qū)。
在靜態(tài)數(shù)據(jù)區(qū)中,所有的字節(jié)默認(rèn)值都是 0x00,利用這一特點(diǎn)可以減少工作量。
如初始化一個(gè)稀疏矩陣,就能省去把所有位置置 0 的操作。
4. 多個(gè)對(duì)象之間數(shù)據(jù)共享
在類中,靜態(tài)成員可實(shí)現(xiàn)多個(gè)對(duì)象的數(shù)據(jù)共享,而且由于隱藏的特點(diǎn),它也同時(shí)保證了安全性。
靜態(tài)成員的初始化格式:<數(shù)據(jù)類型><類名>:: <靜態(tài)成員名>=<值>
- 初始化在類體外進(jìn)行,而且前面不加 static,以免與靜態(tài)變量或?qū)ο蠡煜?/li>
- 初始化時(shí)不加訪問(wèn)權(quán)限控制符 private public 等
- 初始化時(shí)用作用域運(yùn)算符標(biāo)明它所屬的類。由此也可以看出靜態(tài)數(shù)據(jù)成員是類的成員,而不是對(duì)象的成員。
引用靜態(tài)數(shù)據(jù)成員的格式:<類名>:: <靜態(tài)成員名>
下面是幾個(gè)例子:
class Point { public: ?? ?void output() {} ?? ?static void init() ?? ?{ ?? ??? ?x = 0; ?? ??? ?y = 0; ?? ?} private: ?? ?int x; ?? ?int y; } int main(void) { ?? ?Point:: init(); ?? ?return 0; }
報(bào)錯(cuò),因?yàn)榉庆o態(tài)數(shù)據(jù)成員此時(shí)還沒(méi)有分配內(nèi)存。
class Point { public: ?? ?void output() {} ?? ?static void init() ?? ?{ ?? ??? ?x = 0; ?? ??? ?y = 0; ?? ?} private: ?? ?static int x; ?? ?static int y; } int main(void) { ?? ?Point:: init(); ?? ?return 0; }
報(bào)錯(cuò),因?yàn)殪o態(tài)成員變量需要進(jìn)行初始化。
5. 注意
類的靜態(tài)成員函數(shù)屬于整個(gè)類,因此沒(méi)有 this 指針,這就導(dǎo)致了它僅能訪問(wèn)靜態(tài)數(shù)據(jù)和靜態(tài)成員函數(shù)。
不能將靜態(tài)成員函數(shù)定義為虛函數(shù)。
對(duì)靜態(tài)成員進(jìn)行取地址操作會(huì)有些特殊,變量地址是指向其數(shù)據(jù)類型的指針,函數(shù)地址類型是一個(gè) “nonmember 函數(shù)指針”。
由于沒(méi)有 this 指針,所以相當(dāng)于 nonmember 函數(shù),這就有一個(gè)好處:成為一個(gè) callback 函數(shù),使得我們將 C++ 和 C-based X Window 系統(tǒng)結(jié)合,也成功應(yīng)用于線程函數(shù)身上。
父類和子類共享靜態(tài)成員。為了防止父類的影響,可以在子類中定義一個(gè)與父類相同的靜態(tài)變量,以屏蔽父類的影響。這不會(huì)引起錯(cuò)誤,因?yàn)榫幾g器采用了 name-mangling 方法以生成唯一的標(biāo)志。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言解決堆棧括號(hào)匹配問(wèn)題示例詳解
這篇文章主要為大家介紹了C語(yǔ)言堆棧括號(hào)匹配問(wèn)題示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-11-11C++實(shí)現(xiàn)LeetCode(692.前K個(gè)高頻詞)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(692.前K個(gè)高頻詞),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08c++ 移動(dòng)構(gòu)造相關(guān)總結(jié)
這篇文章主要介紹了c++ 移動(dòng)構(gòu)造的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下2021-02-02windows下在vim中搭建c語(yǔ)言開發(fā)環(huán)境的詳細(xì)過(guò)程
這篇文章主要介紹了windows下在vim中搭建c語(yǔ)言開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05C++基于人工智能搜索策略解決農(nóng)夫過(guò)河問(wèn)題示例
這篇文章主要介紹了C++基于人工智能搜索策略解決農(nóng)夫過(guò)河問(wèn)題,簡(jiǎn)單描述了農(nóng)夫過(guò)河問(wèn)題的概念、實(shí)現(xiàn)原理并結(jié)合具體實(shí)例形式給出了C++使用人工智能搜索策略解決農(nóng)夫過(guò)河問(wèn)題的相關(guān)操作技巧,需要的朋友可以參考下2017-12-12C++實(shí)現(xiàn)簡(jiǎn)易的五子棋游戲
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)易的五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05C++設(shè)計(jì)模式之策略模式(Strategy)
這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之策略模式Strategy ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04