命名空間 extern的用法 static全局變量
std是標準庫中的命名空間;
關於extern的用法可以參考文獻http://blog.163.com/sunjinxia%40126/blog/static/9498487920131214502107/,講解的非常清晰
這裏有一個關於static全局變量的講解http://www.360doc.com/content/16/0115/15/15947598_528164347.shtml
引用一個定義在其它模塊的全局變量或函數(如,全局函數或變量定義在A模塊,B欲引用)有兩種方法,一、B模塊中include模塊A的頭文件。二、模塊B中對欲引用的模塊A的變量或函數重新聲明一遍,並前加extern關鍵字。
被extern "C"修飾的變量和函數是按照C語言方式編譯和連接的;
作為一種面向對象的語言,C++支持函數重載,而過程式語言C則不支持。函數被C++編譯後在符號庫中的名字與C語言的不同。例如,假設某個函數的原型為: void foo( int x, int y ); 該函數被C編譯器編譯後在符號庫中的名字為_foo,而C++編譯器則會產生像_foo_int_int之類的名字(不同的編譯器可能生成的名字不同,但是都采用了相同的機制,生成的新名字稱為“mangled name”)。_foo_int_int這樣的名字包含了函數名、函數參數數量及類型信息,C++就是靠這種機制來實現函數重載的。例如,在C++中,函數void foo( int x, int y )與void foo( int x, float y )編譯生成的符號是不相同的,後者為_foo_int_float。 用一句話概括extern “C”這個聲明的真實目的:實現C++與C及其它語言的混合編程。 如果在模塊A中函數聲明了foo為extern "C"類型,而模塊B中包含的是extern int foo( int x, int y ) ,則模塊B找不到模塊A中的函數,模塊B應該用#include "moduleA.h",這樣做的結果就是: (1)模塊A編譯生成foo的目標代碼時,沒有對其名字進行特殊處理,采用了C語言的方式; (2)連接器在為模塊B的目標代碼尋找foo(2,3)調用時,尋找的是未經修改的符號名_foo。
常量默認是靜態聲明的,所以 //file1.c const float pi = 3.14159265; //file2.c extern const float pi; 是不會鏈接成功的,但是 //file1.c extern const float pi = 3.14159265; //file2.c extern const float pi; 是可以鏈接成功的。
為解決c++標準庫中的標識符與程序中的全局標識符之間以及不同庫中的標識符之間的同名沖突,標準c++庫的所有標識符都定義在
一個名為std的命名空間中。如下所示:
引入命名空間的原因:
命名空間是ANSI c++引入的可以由用戶命名的作用域,用來處理程序中常見的同名沖突。
在c++程序中,有大量的變量、函數和類名,如果它們搜存在於同一個全局命名空間中,會導致很多沖突。
1. 自定義函數與標準庫函數 函數重名
2.程序中使用的名字與第三方庫中名稱相同
3.同一項目不同模塊(可能由不同程序員負責)中名字沖突
命名空間的機制,對於聲明於其中的名稱都進行了本地化:
相同的名稱可以在不同的上下文中使用,而不會引起名稱的沖突;
c++中的標準庫被定義到std命名空間中,減少了與用戶自定義名稱的沖突;
在自己的程序中創建自己的命名空間,避免本地化的名稱與外界沖突。
在有沖突的情況下,假如我們自定義過的命名空間 name1和name2中都有標識符name,name在同一個程序中使用的時候就要這樣:
name1::name
name2::name
而不能在開頭用using namespace name1;using namespace name2;了!!
命名空間的使用:
自定義命名空間的時候把一些全局實體分別放在各個命名空間中進行分隔,建立一些互相分隔的作用域,以免產生名字沖突:
namespace ns2//指定命名空間ns1
{
int a;
double b;
class Table{
......
}
namespace ns1
{int age;}
}
引用的時候就是ns2::ns1::age
1.聲明一個命名空間:
namespace 命名空間名
{聲明}
命名空間中的聲明部分可以包括下面的類型:
變量(可以帶有初始化)及常量
函數(可以是定義或聲明)
結構體
類
模板
命名空間(在一個命名空間中又定義一個命名空間,即嵌套的命名空間)
2. 簡化使用命名空間成員的機制
(1)使用命名空間別名
namespace TV=Television;//TV等同Television
這樣在使用Television的時候就可以用TV了。
(2)使用格式:using 命名空間成員名
比如:using ns1::Student;//Student等同ns1::Student
(3)使用:using namespace 命名空間名(容易產生重名沖突)
重名問題的解決:
1. 修改本地名字
2. 加上全局限定符,使用::。 比如 ::distance,這樣寫的原因是當::前面沒有任何名字的時候僅僅表示後面的名字是當前程序本地中的全局變量!!
3. 去掉沖突的外部的命名空間,讓步於本地的名字,當本地要使用外部命名空間中的其他的標識符的時候,用::比如:std::cout
命名空間 extern的用法 static全局變量