【前言】在寫程序時,雖然一直這么用,有點疑惑為甚么引入了頭文件.h還要在加上using namespace std?例如:
1 #include<iostream> 2 using namespace std;//他的作用?cout不應該在頭文件里面定義的函數嗎? 3 int main(0 4 { 5 cout<<"你好"; 6 return 0; 7 }
下面就介紹一下,為什么在引用了iostream頭文件的情況下,想使用cout,還要加上std命名空間。
一、std和stl的關系
stl是標准模板庫,是標准庫的子集。主要是容器、算法、迭代器三個方面,幾乎所有的代碼都采用了模板類和模板函數的方式,這相比於傳統的由函數和類組成的庫來說提供了更好的代碼重用機會。在C++標准中,STL被組織為下面的13個頭文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。標准模板庫里面沒有string,但是他在標准庫里面,用來輸入一個字符串類型。
STD是命名空間的名字,目的是為了避免命名空間污染。模板庫(包括stl)的設計者,特意在庫文件里面加上了命名空間(下面會分析怎么加的)。這樣,我們使用者就可以在定義自己的函數時,定義自己的命名空間。然后在自己定義的命名空間作用域范圍內,使用我們自己定義的、但可能和標准庫里的函數重名的函數。這樣就不會有函數沖突了,使用時注意命名空間的作用域就好了!
二、實現自己的庫和命名空間
一個注意點,標准編碼風格要求接口和實現分離。頭文件包含命名空間的定義類、變量、函數、模板和其他命名空間的聲明。源文件包含命名空間成員的定義部分。
1 //myfile.h 2 #include<string> 3 namespace my_std{ 4 class sales_data{/*各種函數的聲明*/}; 5 } 6 7 //myfile.cc 8 #include"myfile.h" 9 namespace my_std{ 10 //sales_data類中函數的實現 11 } 12 13 //main.cc 14 #include"myfile.h" //若想在main.cc文件加頭文件,如iostream,最好加在引入的文件之前 15 int main() 16 { 17 using my_std::sales_data; 18 sales_data data1,data2; 19 //... 20 return 0; 21 }
由上可以看出,基於接口實現分離。要在.h和.cc文件中加上namespace。這樣的話,就可以在main文件中引入命名空間,在一定作用域下使用特定的函數。
三、在標准庫里實戰分析
標准庫與上面的代碼組織結構類似。但是我看的VS的STL版本中的頭文件是木有.h的,他的聲明和定義是在一起的也叫標准頭文件。在vs里面看一下標准庫源碼(iostream和stl里的vector)。看來分不分離也各有個的使用者吧!我感覺分開更明晰一些!
主程序:
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 int main() 5 { 6 std::vector<int> as; 7 cout<<"a"; 8 getchar(); 9 return 0; 10 }
1、先看iostream的:
宏定義了std,下面所有聲明實現都在命名空間std之下。
2、再看vector的:
標准的c++11沒有.h和.cc之分,轉到聲明和定義都是同一個文件。頭文件及其實現都在vector里面。
我們看到兩個標准頭文件里面都有共同的命名空間,所以命名空間可以是不連續的。