張藝濤 沈木子 方歡
摘要:針對C++中靜態(tài)數(shù)據(jù)成員在多文件編譯環(huán)境中存在的問題,該文深入分析了 C++語言中類靜態(tài)數(shù)據(jù)成員的聲明和訪問方法,定位利用全局變量來實現(xiàn)多文件編譯的弊端,利用extern關鍵字修飾變量來實現(xiàn)多文件編譯的思路,并詳細闡述多文件編譯中extern的用法,并舉了相應的例子來進行例證。
關鍵詞:C++語言;靜態(tài)成員;static;extern;多文件編譯
1 引言
靜態(tài)數(shù)據(jù)成員用static修飾的數(shù)據(jù)成員具有靜態(tài)生存期,可供函數(shù)來調(diào)用該全局變量完成一定需要,可應用局部變量或應用于類中的成員變量。static修飾全局變量,局部變量,函數(shù),作用范圍在同一文件內(nèi)。extern修飾變量的聲明以及函數(shù)的聲明,作用范圍在本文件及多文件范圍。兩者的聲明、定義、存儲卻是不同的。
一個類中聲明一個私有數(shù)據(jù)成員并以static修飾,在類外使用類名限定對該成員進行定義和初始化,實現(xiàn)該變量具有靜態(tài)生存期,以及static修飾函數(shù)成員。在多文件編譯下,類中staitc修飾的變量,編譯器是無法識別。針對這一問題,本文提出使用extern關鍵字,用于靜態(tài)數(shù)據(jù)成員的多文件編譯,并對靜態(tài)數(shù)據(jù)成員的定義和調(diào)用等問題進行了總結(jié)。
2 存在的問題
以一段程序關于點位置的移動來說明,如圖1所示,采用多文件方法將原本的程序分為三部分,其中Point.h文件中聲明一個類,以及類中的無參、有參構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、析構(gòu)函數(shù)、普通函數(shù)和一些數(shù)據(jù)成員;這些類的成員函數(shù)在Point.cpp中進行定義和初始化,其中static修飾的類中變量,用類名限制并進行初始化。在static修飾的數(shù)據(jù)成員用于多文件時,在編譯過程中會出現(xiàn)各種錯誤如圖2所示。
3 問題探索
從圖2可以看出,編譯該段代碼過程中,在Point.cpp文件中出現(xiàn)各種錯誤,在確定代碼準確無誤的情況下,發(fā)現(xiàn)問題可能在static修飾的函數(shù)以及數(shù)據(jù)成員。原程序中的static修飾的count去除,僅剩static修飾的函數(shù),編譯代碼并運行,代碼運行正常。
問題轉(zhuǎn)向static修飾的私有變量。
類的靜態(tài)成員在類定義之外再加以定義,編譯器是否無法找到為它們專門分配的空間呢?在類中直接對其賦值并以const進行修飾。const修飾的量是常量,無法對其再賦值,將該代碼所有有關count的代碼都刪去,在另一編譯文件引用count,并輸出該值。代碼如下:
在圖5中Point類中聲明一個extern變量,會發(fā)現(xiàn)編譯出現(xiàn)問題count的指定存儲類別,說明當聲明一個類的時候并無extern變量的存儲空間,而在源文件中對于extern只是聲明,編譯器沒有實際意義上的賦予存儲空間,只有在定義后,編譯器在此標記存儲空間在執(zhí)行時加載內(nèi)并初始化,間接說明extern修飾的變量無法在類中使用。extern可以置于變量或者函數(shù)前,以表示變量或者函數(shù)的定義在別的文件中,提示編譯器遇到此變量和函數(shù)時,在其他模塊中尋找在其定義全局變量在外部使用聲明時,extern關鍵字是必須的,如果變量沒有extern修飾且沒有顯式的初始化,同樣成為變量的定義,因此此時必須加extern,而編譯器在此標記存儲空間在執(zhí)行時加載內(nèi)并初始化為0。而局部變量的聲明不能有extern的修飾,且局部變量在運行時才在堆棧部分分配內(nèi)存。全局變量或函數(shù)本質(zhì)上講沒有區(qū)別,函數(shù)名是指向函數(shù)二進制塊開頭處的指針。而全局變量是在函數(shù)外部聲明的變量。函數(shù)名也在函數(shù)外,因此函數(shù)也是全局的。聲明可以是多次,但是定義只能是一次,否則編譯器會出錯。extern int i;為聲明,不是定義。int;既是聲明也是義。使用externa 來聲明一個數(shù)組時,extern char p[];定義于 .h文件.當用指針extern char *p;聲明在.h文件中是錯誤的。將會導致系統(tǒng)崩潰。p在這里被聲明為extern char* p ,而它原來的定義卻char p[10].這種情況,當用p[i]這種形式提取這個聲明的內(nèi)容時,實際上得到的是一個字符。但按照上面的方法,編譯器卻把它當成是一個指針,把ASCII字符解釋成為地址顯然出錯,如果此時程序無意義,不會污染空間內(nèi)容。否則,會污染程序地址空間的內(nèi)容,并出現(xiàn)莫名其妙的錯誤。
5 總結(jié)
對比static以及extern關鍵字,闡明兩者相同與區(qū)別,同時發(fā)現(xiàn)static關鍵字在多文件編譯單元的弊端,使用關鍵字extern解決多文件編譯問題,最后總結(jié)extern用法。此次實驗不僅是static以及extern的用法說明,更是在代碼繁多情況下,多文件來編譯使編寫代碼區(qū)塊分工明確。當代碼的內(nèi)容變得復雜,既不會使程序員混淆,同時也能更好地完成任務。
參考文獻:
[1] 趙娟.C++語言中共享機制的實現(xiàn)[J].電腦知識與技術,2019,15(4):212-213.
[2] 張永,方安仁,劉治生.C++語言中靜態(tài)數(shù)據(jù)成員的研究[J].陜西理工學院學報:自然科學版,2005,21(4):22-24.
[3] 聶豐英.淺談靜態(tài)成員在C++中的應用[J].硅谷, 2008(17):27-27.
[4] 鄭莉.C++語言程序設計[M].4版.北京:清華大學出版社,2012.
【通聯(lián)編輯:王力】