《C++ Primer Plus 第6版》第九章學習筆記
存儲持續性
自動存儲持續性:函數中聲明的變量;
靜態存儲持續性:函數外定義的變量和用static關鍵字定義的變量;
線程存儲持續性:thread_local聲明的變量,其聲明週期與所在線程相同;
動態存儲持續性:new運算符分配的內存,由delete運算符釋放,稱爲自由存儲或者堆(heap)。
作用域和鏈接性
作用域描述了名稱在文件(翻譯單元)的多大範圍內可見。
鏈接性描述了名稱如何在不同單元間共享。
當函數中有與全局變量相同名稱的變量(如var)時,函數中的變量會隱藏全局變量。在函數可以通過作用域解析運算符“::“訪問全局變量(如::var)。
//代碼片段 int num = 0; void doNum() { int num = 11; cout << "in doNum()" << endl; ::num+=1; //修改全局的num cout << "::num = " << ::num << endl; // 輸出全局num cout << "num=" << num << endl; // 輸出函數中的num }
靜態持續變量
靜態持續變量有3種鏈接性:
-
外部鏈接性:可在其他文件中訪問,定義於代碼塊之外;
-
內部鏈接性:只能在當前文件中訪問,定義於代碼塊之外並且使用static限定符;
-
無鏈接性:只能在當前函數或者代碼塊中訪問,定義於代碼塊之內並且使用static限定符。
int global_var = 1; // 外部鏈接性 static int onefile_var = 2; //內部鏈接性 void foo() { static int nolink_var = 3; //無鏈接性 }
所有靜態持續變量,如果沒有被初始化,則其所有位都被設置爲0,即零初始化(zero-initialized)。
每個使用外部變量的文件,都必須聲明該外部變量:要在多個文件中使用外部變量,只需要定義該變量一次,在其他使用該變量的文件中必須使用extern對其進行聲明。
注意:用extern聲明外部變量的時候,不要給其賦值,否則聲明就成了定義。
下面代碼演示兩個cpp文件:rgb_color.cpp中定義了外部鏈接性的靜態持續變量,在main.cpp中用extern聲明要用到的外部變量。
//rgb_color.cpp int color_r = 0xff0000; int color_g = 0x00ff00; int color_b = 0x0000ff;
//main.cpp #include <iostream> using namespace std; extern int color_r; //聲明外部變量 int main() { cout << "Red:" << hex << color_r << endl; return 0; }
在文件中使用static定義內部鏈接性的靜態變量後,在此語句之後的對應變量爲該變量,即隱藏了外部同名變量。如果在該語句之前定義了某個函數,且函數中使用extern聲明瞭同名的變量,則在該函數中會使用外部鏈接性的外部變量。
例如,將上面代碼中main.cpp修改如下:
//main.cpp #include <iostream> using namespace std; extern int color_r; int green() { extern int color_g;//使用外部變量,即0x00ff00; return color_g; } // - start here, make a difference ... static int color_g = 32; //定義內部鏈接性變量; int green2() { extern int color_g; //仍然使用內部鏈接性,即32 return color_g; } int main() { cout << "green() = " <<hex << green() << endl; // 0x00ff00 cout << "Red:" << hex << color_r << endl;//0x20 cout << "Green:" << color_g << endl; //<< dec cout << "green() = " << green() << endl; // 0x00ff00 cout << "green2() = " << green2() << endl; //0x20 return 0; }
在”static int color_g = 32; //定義內部鏈接性變量;“這一語句之後,color_g都爲32,即0x20,只有green函數中的是外部變量。
const限定符
在C++中,全局變量默認爲外部鏈接性,但const全局變量的鏈接性爲內部的。如果希望某個常量鏈接性爲外部,在定義的時候需要使用extern關鍵字,在其他使用該常量的文件中要用extern來對其進行聲明:
extern const int gloabal_const_data = 100;
函數鏈接性
默認情況下,函數的鏈接性爲外部,在要使用外部文件定義的函數的文件中,只需聲明該函數原型即可,extern關鍵字爲可選。
通過使用static關鍵字,可以將函數鏈接性設置爲內部,即只能在一個文件中使用。注意,聲明和定義中都要用static關鍵字。
語言鏈接性
C語言鏈接:extern "C"
C++語言鏈接:extern "C++"
以上兩者用在函數原型上,指定要使用的約定。