cpp源文件與h頭文件關系 我們知道C++支持多種編程范式,可以完全用采用面向過程,不去用類,當然了很少有人這樣做,一般是結合面向過程與面向對象. 那假如有一些處在不同源文件中的變量和函數(不是類中的變量成員或成員函數),我們要使用不同源文件中的變量或函數時咋整呢? 在面向對象中我們使用一個個類的時候自然是用頭文件引用下就OK.但現在沒有類,只是一個個變量和函數,也能用引用頭文件嗎 ? 這得看情況,有時可以,有時不行.如果頭文件中只有外部聲明沒有任何定義,那引用頭文件完全沒有問題.如果頭文件中有定義的話,如果只被一個cpp文件引用則沒問題,如果被多個cpp文件引用就會出現重復定義的錯誤.(注:編譯器是以cpp文件為單位編譯,如果某個h頭文件沒有被引用的話相當於被拋棄不用了.引用頭文件時預編譯時只是簡單的把頭文件復制到引用它的cpp文件中.) extern外部聲明 假如在有one.cpp和two.cpp兩個源文件. //one.cpp中 --------------------------------------------------- #include <iostream> using namespace std; int number = 123; //number的定義 void Print() {cout<<"hi,i am one.cpp"<<endl;} //two.cpp中 -------------------------------------------------------- #include <iostream> using namespace std; extern int number;//這就是所謂的外部聲明,此處extern不可省 extern void Print(); //此處extern可以省略. cout<<number; //結果為123 Print(); //輸出i am one.cpp 在two.cpp中是怎麼得到one.cpp中的number的值的呢,由於用extern int number這樣聲明了下,表明number在其他源文件中有定義,鏈接器就會幫助去其他源文件中找的. 假如把上面two.cpp中的extern關鍵字去掉. 編譯時不會出錯.但鏈接時出錯了,重復定義了.因為one.cpp中已經定義了個number,不能再定義一個相同的了. static 內部連接 上面的例子中我們知道one.cpp和two.cpp中同時寫上int number會出錯,說重復定義了.但如果這樣 //one.cpp中 static int number = 123; //two.cpp中 static int number; //沒顯式賦值,會默認賦予0 此時卻不會出錯.因為定義變量時默認是外部連接的.而加上關鍵字static表示是靜態變量,是內部連接,鏈接器不會去看不同cpp編譯成的obj文件中有重名的靜態變量不. 當用static修飾後就不能再使用extern修飾了. //one.cpp中 static int number = 123; //two.cpp中 extern int number; cout<<number; 此時會出錯,因為extern聲明的number找不到定義.因為one.cpp的number用static修飾表明是內連接了. const關鍵字 //one.cpp中 const int number = 123; //two.cpp中 const int number = 321; 這裡達到的效果與static一樣,都屬於內部連接,所以不會出錯.唯一不同的時const表示常量,定義時必須顯式賦予值,且賦值後不能再改變它的值. 不過const還有另外一個特性就是可以和extern一起用. 比如在two.cpp中這樣寫 extern const int number; // cout<<number; //輸出的值是one.cpp中的number值123 inline與static函數也是內部連接的 //one.cpp中 void Test() { } //two.cpp中 void Test() { } 這樣編譯時會報錯,重復定義了.但如果把上面的兩個void Test都改成inline void Test() { }或者static void Test() { }則不會出錯.//注意這裡講的inline函數指的是全局函數,不是類裡面的inline函數. 所以函數跟一般變量差不多.沒任何修飾的就默認是外部連接,有static修飾的則是內部連接.另外沒有const函數這一說,只有在類中才可以在函數後面加個const來修飾