原創 C++做用域 (一)

1概述

在全部的計算機程序中,一個基本的目標是操做一些數據,而後得到一些結果。爲了操做這些數據,須要爲這些數據分配一段內存,咱們能夠將這段內存稱爲變量。爲了方便操做,以及程序可讀性方面的考慮,須要使用一個有意義的名稱來引用這段內存,這個名稱就是變量名。ios

將名稱和一段內存關聯起來的工做能夠分紅兩個階段來進行,分別是變量的聲明和定義。在變量聲明的時候,只是引入了一個名稱,該名稱並無和一段特定的內存關聯。也就是說,在聲明變量的時候,只是引入了一個助記符,並無執行內存分配。在定義變量的時候,將前面聲明過程當中引入的名稱關聯到了一段特定的內存,內存的大小由變量的類型決定。也就是說,在定義變量的時候,真正執行了內存分配。在有的狀況下,變量的聲明和定義是須要分開進行的,如:全局變量的聲明和定義,能夠在多個文件中使用該變量;而在某些狀況下,使用一個語句就能夠完成變量的聲明和定義,如:局部變量的聲明和定義。只須要在一個文件中使用該變量。程序員

在C++程序中,當聲明並定義了一個變量之後,須要關注以下兩個問題:算法

  1. 由聲明引入的變量名能夠用在什麼地方,如何進行名字解析;
  2. 由定義分配的內存的生命週期是多少。

爲了解決這兩個問題,就須要引入做用域的概念。做用域是C++程序中的一段區域,通常用正反兩個花括號來界定它的範圍。在同一個做用域範圍內,一個名稱只能惟一關聯到一個實體,這個實體能夠是變量,函數,類型,模版等。也就是說,在同一做用域範圍內,不一樣的實體必須對應不一樣的名稱,絕對不容許出現兩個不一樣的實體對應同一個相同的名稱的狀況。一個名稱能夠和不一樣做用域中的不一樣實體相對應。也就是說,對於同一個名稱,在不一樣的做用域中能夠重複使用。數組

在本文的後續部分,將對各類類型的做用域進行描述,而且介紹在做用域中進行名字解析的規則。緩存

2做用域的分類

2.1概述

咱們能夠將整個C++程序(在程序中包括各類類型,函數,模版,變量等,而且分佈在不少個*.cpp文件中)當作一個很大的總體區域。爲了方便對C++程序中已經定義的各類類型,函數,模版,變量的管理,能夠把這片大的區域劃分紅一片片小的命名區段。而後根據各個類型,函數,模版,變量的功能以及用途等,再把這些類型,函數,模版,變量等分別放置在不一樣的區段中。這些小的區段叫作做用域,C++程序支持四種形式的做用域,分別是:名字空間做用域,類域,局部做用域,語句做用域。安全

名字空間做用域就是程序員利用名字空間定義在C++程序中劃分出來的一塊比較大的程序區段。在該程序區段內部,能夠定義類型,函數,模版,變量。名字空間做用域能夠跨越多個*.cpp文件而存在。在名字空間做用域內部還能夠繼續定義其餘的名字空間做用域,也就是說,名字空間做用域是能夠互相嵌套的。數據結構

全局做用域是C++程序最外層的名字空間做用域,也是最大的名字空間做用域。全局做用域自然存在於C++程序中,它不須要由程序員人爲地定義。在全局做用域內部,能夠包含其餘的,由程序員定義的名字空間做用域,以及沒有包含在其餘名字空間做用域中的類型,函數,模版,變量。在全局做用域中定義的變量是全局變量,在全局做用域中定義的函數是全局函數。函數

在C++程序中,每定義一個類就會引入一個類域。類體所包含的範圍就是類域的範圍,在類中定義的全部成員都屬於該類域。類域位於名字空間做用域內部,該名字空間做用域多是全局做用域,也多是用戶定義的名字空間做用域。工具

每個函數體內部都是一個局部做用域。該做用域起始於函數體的左花括號「{」,結束於函數體的右花括號「}」。每個函數都有一個獨立的局部做用域。在局部做用域內定義的變量都是局部變量。spa

在C++程序中,當要求使用單個語句,但程序邏輯卻須要不止一個單個語句的時候,咱們可使用複合語句。複合語句一般被稱爲塊,是用花括號括起來的一些單個語句的集合。在複合語句花括號內部的區段也屬於局部做用域。

有些語句存在控制結構,而且容許在控制結構中定義變量。如:

 

示例一:

for ( int K = 0; K < 100;K++ )

  cout << K;     //該行語句屬於語句做用域範圍,K僅在這一行有效。

示例二:

for (int K = 0; K < 100;K++)

{

   … //其餘代碼

   Cout << k;   //花括號內部是複合語句,都屬於語句做用域。K在整個花括號內有效。

   … //其餘代碼

}

 

    從控制語句的開始到控制語句結束這一段區域被稱爲語句做用域。在該控制結構中定義的變量,僅在該語句做用域內有效。如:示例二中,K在花括號內有效,或者示例一中,僅在語句「cout << K;」中有效。語句做用域是最小的做用域。

全局做用域,名字空間做用域,類域,局部做用域,語句做用域之間的關係以下圖所示:

 

從上圖能夠看出,在全局做用域中,定義了兩個名字空間H和K。名字空間H又分別位於兩個CPP文件A和B中。因而可知,名字空間做用域是能夠跨越CPP文件的。在名字空間K中,除了定義了類型外,又定義了一個名字空間N,因此說,名字空間之間是能夠互相嵌套的。另外,在名字空間中能夠定義類,函數,變量,模版等。

在全局做用域中,除了定義的名字空間H和K外,又定義了一個類D,以及全局函數,全局變量和模版。在類D中,定義了一些成員函數,所以引出了局部做用域。在局部做用域中,若是存在控制語句,就會存在語句做用域。

在各類做用域中定義的變量或對象,其生命週期從該變量被定義開始,直到該做用域結束。如:在全局做用域中定義的變量,其生命週期是整個程序的生命週期,程序運行結束,該變量被釋放;在局部做用域中定義的變量,其生命週期是從定義該變量開始,直到該函數執行完畢。

2.2名字空間做用域

2.2.1名字空間的意義

使用名字空間能夠在必定程度上解決命名衝突的問題。假設沒有名字空間,那麼在C++程序中,全部的實體,如:函數,類型,變量,模版等,都必須被放置在全局域中做爲全局實體而出現。在全局域中,這些實體必須具備惟一的名稱,不容許存在多個實體同名的狀況。所以,當在全局域中引入一些第三方開發的類庫的時候,必需要保證第三方類庫中命名的實體與全局域中命名的實體在命名方面不衝突。可是,這是很難保證的。爲了解決這個問題,就引入了名字空間的概念。

第三方開發方在開發類庫的時候,能夠首先聲明一個名字空間,每個用戶聲明的名稱空間都表明一個不一樣的名字空間域。在該名字空間中,能夠包含嵌套其餘的名稱空間,以及函數,類型,變量,模版等的聲明和定義。在該名稱空間內部聲明的實體被稱爲名稱空間成員。用戶在名字空間中聲明的每一個實體的名字必須是惟一的,不容許重名。由於在不一樣用戶聲明的名字空間中引入了不一樣的域,因此在這些由不一樣用戶聲明的名字空間中可使用相同的名稱。經過這種方式解決了命名衝突的問題。

在使用名字空間中的成員的時候,名字空間成員的名字會自動與該名字空間重合,或者說被其限定修飾。如:在名字空間A中聲明的類B,它的名字是:A::B。

2.2.2名字空間的定義

用戶聲明的名字空間以namespace關鍵字開頭,後面是名字空間的名稱。名字空間的範圍以花括號界定,具體的格式以下:

namespace mySpace //mySpace是名字空間的名稱

{

   Class myClass { … }; //類定義

   Int myFunction(int para1,int para2); //函數的聲明

   Extern double myVar; //變量的聲明

}

    在上面的示例中,聲明瞭一個名稱爲mySpace的名字空間,該名字空間的做用域由花括號界定,在花括號內部的部分都屬於該名字空間的做用域。在該名字空間中,定義了一個類:myClass,聲明瞭一個函數:myFunction,以及一個變量myVar。它們都是該名字空間的成員。

   

用戶聲明的名字空間能夠位於全局做用域中,也能夠位於其餘的名字空間的做用域中。在當前的做用域中,名字空間的名稱是惟一的,不能與其類型的實體重名。

在同一個做用域中,能夠屢次聲明相同名稱的名字空間。在這種狀況下,將會實現名字空間的累加。好比,A.h頭文件和A.cpp源文件都位於全局做用域中,在這兩個文件中分別聲明以下的名字空間:

A. h文件的代碼實現:

namespace mySpace //在這裏實現了函數和變量的聲明,屬於接口部分。

{

   Int AddData (int para1,int para2); //函數的聲明

   Extern double myVar;  //變量的聲明

}

B.cpp文件的代碼實現:

Include 「A.h」

namespace mySpace // 在這裏實現了函數和變量的定義,屬於實現部分。

{

   Int AddData(int Para1,int Para2) //函數的定義

   {

      Return Para1+Para2;

   }

 

    Double myVar = 3.14;  //變量的定義,並初始化。

}

在這裏,存在這樣一個規則:在同一個做用域中,若是新聲明的一個名字空間的名稱與前面聲明過的名字空間的名稱同名,那麼這個後聲明的名字空間就是前面聲明的名字空間的累加,這兩部份內容屬於同一個名字空間;若是新聲明的這個名字空間不與當前做用域中任何名字空間同名,那麼就會定義一個新的名字空間。

在上面的示例中,A.h和A.cpp文件位於全局做用域中。在全局做用域中,兩次聲明的名字空間具備相同的名稱:mySpace。所以,認爲這兩次聲明的名字空間屬於同一個名字空間。

經過對上面所描述的規則的使用,在程序設計的時候,能夠根據須要,將名字空間的聲明拆分紅若干個部分來實現,只要這幾個部分的聲明都在同一個做用域中便可。這個規則的一個典型應用就是:實現接口和具體實現的分離。

在上面的示例中,咱們將函數AddData和變量myVar的聲明放在了A.h頭文件中,而將它們的定義放在了另一個A.cpp的源文件中。 A.h頭文件實現的是函數庫的接口的,而A.cpp文件中的內容則是針對接口的實現。所以,在程序設計和開發的時候,這兩部份內容能夠分別由不一樣的人在不一樣的時間實現。經過這種方式,實現了接口和具體實現分離的原則。

 

2.2.3名字空間成員的定義

當定義了名字空間之後,就能夠想名字空間中添加成員。這些被添加的成員能夠是:類型,函數,變量,模版等。能夠經過兩種方式向名字空間中添加成員。

第一種方式是:在定義名字空間的同時,在名字空間的花括號內直接完成名字空間成員的定義。也就是說,不管名字空間的定義是採用累加的形式,仍是該名字空間分佈在多個物理文件中,名字空間成員的聲明和定義都在名字空間內部進行。具體示例以下:

方式一:在名字空間中直接完成成員的定義。成員的定義不在劃分爲聲明和定義兩部分。

Namespace mySpace

{

   Double myVar = 3.14;

   Int myFunction(int Para1)

   {

       Return Para1*10;

   }

}

方式二:在名字空間中先完成成員的聲明,而後採用名字空間累加的方式,在其餘部分完成成員的定義。這個「其餘部分」,能夠是其餘的物理文件,也能夠是同一個物理文件。

Namespace mySpace

{

Extern double myVar;

Int myFunction(int Para1);

}

 

Namespace mySpace

{

Double myVar = 3.14;

Int myFunction(int Para1)

{

   Return Para1*10;

}

}

在上面的代碼中,在定義了名字空間的同時(不管是採用累加方式,仍是一次性完成),在名字空間內部完成了函數myFunction和變量myVar的定義。名字空間的定義和名字空間成員的定義同步完成。

第二種方式是:在定義名字空間的時候,僅僅在名字空間中完成對名字空間成員的聲明,而名字空間成員的定義在名字空間以外被實現。具體代碼以下:

//首先在一個文件中完成名字空間的定義,以及名字空間成員的聲明。通常狀況下,該文件爲頭文件(A.h)。

Namespace mySpace

{

Class myClass {….};//聲明一個類型

myClass myFunction(myClass Para1);//聲明一個函數,該函數返回myClass類型,並以myClass類型爲參數。

}

在上面的代碼中,完成了對名字空間mySpace的定義,同時在名字空間內部,完成了類myClass的定義,以及對函數myFunction的聲明。接下來須要在其餘地方,名字空間之外,完成對名字空間成員myFunction函數的定義。具體代碼以下:

//實現函數myFunction定義的位置,能夠是另一個文件,通常爲cpp文件,可是也能夠在原來的頭文件中(通常不會這麼幹)。

#include 「A.h」

mySpace::myClass mySpace::myFunction(myClass Para1)

{

    //下面完成函數的具體實現。

   …

}

在上面的代碼中,咱們能夠看到兩處差別。一處是函數的返回值類型,myClass被名字空間mySpace限定修飾了;而在函數的參數類型處,myClass直接使用,沒有被名字空間mySpace限定修飾。

這裏存在這樣一個規則:在函數的限定修飾名稱「mySpace::myFunction」以後,直到方括號結束的區域都屬於mySpace名字空間的做用域範圍。也就是上面代碼中的紅色部分。

也就是說名字空間的做用域可能會有兩部分組成,在大多數狀況下,名字空間的做用域是由定義名字空間的時候,名字空間體的花括號界定的。可是,當在名字空間以外定義名稱空間的成員的時候,在名字空間成員的限定修飾名以後直到結束花括號(」 }」),或者分號(;)的部分都屬於該名字空間做用域範圍。

所以,在上面的代碼中,參數的類型不須要被限定修飾,由於那個區域是屬於名字空間做用域內的;而函數的返回類型必需要被限定修飾,由於那個區域不屬於名字空間的做用域內。

另外還須要注意,在名字空間以外實現名字空間成員的定義的時候,要有一個前提,那就是:名字空間成員的聲明必須在名字空間以內實現。

2.2.4名字空間成員的使用

在C++程序中,使用名字空間的方式封裝一些函數庫或者類庫的時候,通常狀況下,一般的作法是這樣的:首先在一個頭文件中定義一個名字空間,而後在該名字空間的定義中聲明全部的名字空間成員,如:函數,類型,變量等。以後將這個頭文件引入到一個cpp文件中,而且在這個cpp文件中實現全部名字空間成員的定義。具體示例以下:

-----------------A.h------------------------------//頭文件名稱

namespace myCPlusPlusFunctionsV1.0

{

     Class myClass { …//類成員的聲明 }; //定義一個類型

     Extern double myVar; //聲明變量

     Void DealClass(myClass*); //聲明函數

}

-----------------A.cpp--------------------------//源文件

#include 「A.h」

Namespace myCPlusPlusFunctionsV1.0

{

myClass:: myClass() { … // myClass構造函數的實現}

//其餘myClass類成員的定義。

double myVar = 3.14;//變量的定義

void DealClass(myClass*pClass)

{

   …//函數的具體實現。

}

}

 

在使用這些函數庫或者類庫的時候,首先須要將這個定義了該名字空間的頭文件引入,而後開始使用該名字空間中的一些成員。在使用名字空間成員的時候,有三種方式:

第一種方式:域操做符方式。經過域操做符加名字空間名稱的方式對名字空間成員名進行限定修飾。具體代碼以下:

------------------otherCPlusPlusFile.cpp-------------------------

#include 「A.h」

Void main()

{

   myCPlusPlusFunctionsV1.0::myClass *pClass = new myCPlusPlusFunctionsV1.0::myClass;

   myCPlusPlusFunctionsV1.01::DealClass(pClass);

}

在上面的代碼中,「::」是域操做符。名字空間成員的聲明被隱藏在名字空間之中,因此,名稱空間的成員名稱不會與當前做用域中的對象實體名稱產生衝突。在使用名字空間成員的時候,可使用名字空間名+域操做符+名字空間成員名稱的方式將名字空間成員引入到當前的做用域中。不然,在當前做用域中,編譯器不會找到名字空間的成員。

域操做符也能夠被用來引用全局做用域的成員。由於全局做用域沒有名稱,因此使用以下的符號:

 ::member_name

指向全局名字空間的成員。當全局名字空間成員的名稱被局部做用域中的名字隱藏的時候,但又須要在局部做用域中使用全局成員的時候,就可使用這種引用方式。

在上面的示例中,名字空間的名稱「myCPlusPlusFunctionsV1.0」比較長,在使用的時候,可能會不方便,所以,C++在處理這個問題的時候,引入了名字空間別名的概念。

    所謂名字空間別名就是爲已經定義的名字空間取一個其餘的、替代性的名稱,一幫狀況下,這個名稱是簡短的,容易記憶的。具體使用方式以下:

 

------------------otherCPlusPlusFile.cpp-------------------------

#include 「A.h」

Namespace myC++ = myCPlusPlusFunctionsV1.0;

Void main()

{

   myC++::myClass *pClass = new myC++::myClass;

   myC++::DealClass(pClass);

}

在上面的代碼中,爲名字空間「myCPlusPlusFunctionsV1.0」定義了一個別名「myC++」。以後在引用該名字空間成員的時候,就可使用該別名。

定義名字空間別名的格式是:以關鍵字namespace開頭,後跟名字空間的別名,而且等於前面定義好的名字空間的名稱。

第二種方式:使用using 聲明,一次引入一個名字空間成員。

Using 聲明的做用是:使一個名字空間成員在當前做用域中可見,可見的範圍是從using聲明的語句開始,直到當前做用域結束。若是在using聲明語句以後,在當前做用域中又嵌套了其餘的做用域,那麼using聲明在當前做用域中的嵌套做用域中也一樣有效。

Using聲明以關鍵字using開頭,後跟名字空間的成員名稱。該成員名稱必須是名字空間名稱+域操做符+名字空間成員名稱形式的限定修飾名稱。具體代碼以下:

//名字空間的定義

Namespace mySpace

{

Int myFunction(int Para)//在名字空間中定義了一個函數

{

     Return Para*10;

}

}

//在全局做用域中使用using聲明,將名字空間成員名引入當前做用域。

Using mySpace::myFunction;

//開始使用名字空間的成員

Void main()

{

   //也能夠在此位置使用using聲明,即在局部做用域使用using聲明。

   myFunction(10);//使用名字空間的成員。由於使用了using聲明,因此不須要使用限定修飾的形式。名稱myFunction從using聲明開始,直到當前做用域結束。

}

在上面的代碼中,首先定義了一個名字空間,並在名字空間中定義了一個函數。而後在全局做用域中使用了using聲明。以後,在main函數中使用名字空間的成員函數myFucntin。

能夠在全局做用域,名字空間做用域,局部做用域中使用using聲明。在使用了using 聲明之後,一次只能從源名字空間向當前做用域中引入一個名字空間成員,但能夠屢次使用using聲明。若是該名字空間成員是函數,而且在該名字空間中具備多個重載,那麼在使用using聲明的時候,全部的重載函數都會被引入到當前的做用域中。被引入的名字空間成員名只在當前做用域中有效,而且名稱惟一。這個被引入的名字空間成員名會隱藏當前做用域外圍做用域中的同名名稱,也會被當前做用域的嵌套做用域中的同名名稱隱藏。具體狀況見以下代碼:

namespace mySpace

{

   Int myIntVar = 10;//定義一個整型變量。名字空間成員。

}

 

Int myIntVar = 100;//全局變量

Int main()

{

Using mySpace::myIntVar;//該using聲明隱藏了全局變量myIntVar。

Int k = 10;

K = k + myIntVar;//使用的是名字空間的成員變量,因此k的值等於20.

K = K + ::myIntVar;//這裏使用的是全局變量,因此k的值等於110.

{

     Int myIntVar = 50;//在此語句做用域中聲明的變量隱藏了前面using聲明中引入的變量。

    Int a  = myIntVar ;//a = 50

    Int b  = ::myIntVar;//b = 100;

    Int C  = mySpace::myIntVar;//c = 10;

}

}

使用using聲明將名字空間的成員引入到當前做用域的時候,除了重載函數之外,被引入的成員名稱不能與當前做用域中定義的對象實體重名,不然會引發錯誤。

第三種方式:使用using 指示符,一次引入全部名字空間成員。

Using指示符以關鍵字using 開頭後跟關鍵字namespace,最後是名字空間的名稱。該名字空間的名稱必須在前面已經定義。其做用域從using指示符開始,直到當前做用域結束。使用using指示符之後,將會把名字空間中的全部成員引入到當前做用域。具體的代碼以下:

//定義名字空間

Namespace mySpace

{

Int myFunction(int Para)

{

   Return Para*10;

}

Int myVar = 100;

}

//使用using指示符,將名字空間的全部成員引入到當前做用域。目前是全局做用域。

Using namespace mySpace;

Void main()

{

Int k = myVar + 10;//使用using指示符之後,能夠直接使用名字空間中的成員,就好像該//名字空間的成員在當前做用域中定義的同樣,不須要限定修飾。

myFunction(k);

}

在上面的代碼中,首先定義了一個名字空間mySpace,同時在名字空間中定義了一個函數myFunction,以及一個變量myVar。而後使用using指示符將該名字空間中的成員引入到了全局做用域中。以後,在main函數中使用名字空間的成員,使用的時候,不須要限定修飾,就好像使用當前名字空間中定義的成員同樣。

在當前做用域使用using指示符之後,被引用的名字空間將與當前的做用域合併,名字空間中的成員就好像在當前做用域被定義同樣。所以,在當前做用域中,不能定義與名稱空間成員重名的對象。不然會所以錯誤。

2.2.6 標準名字空間std

在名字空間的概念被提出以前,在C++中就已經存在了大量的庫函數。這些庫函數有的是標註C形式的,也有的是標準C++形式的。在聲明這些庫函數的時候,按照其功能和類別,它們被劃分到不少不一樣的頭文件中,如:iostream.h,complox.h,stdio.h。當名字空間的概念被提出以後,這些庫函數被從新整理,將它們的聲明和定義放到了名稱空間名稱爲std的名稱空間中。它們被稱爲標準C++庫。

可是爲了向前兼容之前實現的C++程序,在對這些庫函數進行整理的時候,建立了新的頭文件,並採用了新的命名規則,以區分原有的庫函數。具體的處理方式描述以下:

  1. 對於支持C++的頭文件,如:<iostream.h>,在被從新整理以後,它的名稱爲<iostream>去掉了頭文件的擴展名。新的頭文件所包含的功能與舊頭文件基本相同,可是它們在std名字空間中;
  2. 對於支持C標準的頭文件,如:<stdio.h>,在被從新整理以後,它的名稱爲<cstdio>,在名稱的前面加上了前綴字符「C」,並去掉擴展名。新的頭文件所包含的功能與舊的頭文件基本相同,可是它們在std名字空間中。
  3. 原有舊的C++標準頭文件,如<iostream.h>,依然被支持,它們不在名字空間std中;
  4. 原有舊的C標準頭文件,如<stdio.h>,依然被支持,它們不在名字空間std中。
      

具體狀況以下圖所示:

 

在C++標準庫中,一共50個頭文件,10個分類,其中18個C庫功能。與宏相關的名稱在全局做用域中定義,其餘的在名字空間std中被定義。

   按照分類,C++標準庫的詳細狀況以下表所示:

C1. 標準庫中與語言支持功能相關的頭文件

頭文件

描        述

<cstddef>

定義宏NULL和offsetof,以及其餘標準類型size_t和ptrdiff_t。與對應的標準C頭文件的區別是,NULL是C++空指針常量的補充定義,宏offsetof接受結構或者聯合類型參數,只要他們沒有成員指針類型的非靜態成員便可。

<limits>

提供與基本數據類型相關的定義。例如,對於每一個數值數據類型,它定義了能夠表示出來的最大值和最小值以及二進制數字的位數。

<climits>

提供與基本整數數據類型相關的C樣式定義。這些信息的C++樣式定義在<limits>中

<cfloat>

提供與基本浮點型數據類型相關的C樣式定義。這些信息的C++樣式定義在<limits>中

<cstdlib>

提供支持程序啓動和終止的宏和函數。這個頭文件還聲明瞭許多其餘雜項函數,例如搜索和排序函數,從字符串轉換爲數值等函數。它與對應的標準C頭文件stdlib.h不一樣,定義了abort(void)。abort()函數還有額外的功能,它不爲靜態或自動對象調用析構函數,也不調用傳給atexit()函數的函數。它還定義了exit()函數的額外功能,能夠釋放靜態對象,以註冊的逆序調用用atexit()註冊的函數。清除並關閉全部打開的C流,把控制權返回給主機環境。

<new>

支持動態內存分配

<typeinfo>

支持變量在運行期間的類型標識

<exception>

支持異常處理,這是處理程序中可能發生的錯誤的一種方式

<cstdarg>

支持接受數量可變的參數的函數。即在調用函數時,能夠給函數傳送數量不等的數據項。它定義了宏va_arg、va_end、va_start以及va_list類型

<csetjmp>

爲C樣式的非本地跳躍提供函數。這些函數在C++中不經常使用

<csignal>

爲中斷處理提供C樣式支持

C2. 支持流輸入/輸出的頭文件

頭文件

描        述

<iostream>

支持標準流cin、cout、cerr和clog的輸入和輸出,它還支持多字節字符標準流wcin、wcout、wcerr和wclog。

<iomanip>

提供操縱程序,容許改變流的狀態,從而改變輸出的格式。

<ios>

定義iostream的基類

<istream>

爲管理輸出流緩存區的輸入定義模板類

<ostream>

爲管理輸出流緩存區的輸出定義模板類

<sstream>

支持字符串的流輸入輸出

<fstream>

支持文件的流輸入輸出

<iosfwd>

爲輸入輸出對象提供向前的聲明

<streambuf>

支持流輸入和輸出的緩存

<cstdio>

爲標準流提供C樣式的輸入和輸出

<cwchar>

支持多字節字符的C樣式輸入輸出

C3. 與診斷功能相關的頭文件

頭文件

描        述

<stdexcept>

定義標準異常。異常是處理錯誤的方式

<cassert>

定義斷言宏,用於檢查運行期間的情形

<cerrno>

支持C樣式的錯誤信息

C4. 定義工具函數的頭文件

頭文件

描        述

<utility>

定義重載的關係運算符,簡化關係運算符的寫入,它還定義了pair類型,該類型是一種模板類型,能夠存儲一對值。這些功能在庫的其餘地方使用

<functional>

定義了許多函數對象類型和支持函數對象的功能,函數對象是支持operator()()函數調用運算符的任意對象

<memory>

給容器、管理內存的函數和auto_ptr模板類定義標準內存分配器

<ctime>

支持系統時鐘函數

C5. 支持字符串處理的頭文件

頭文件

描        述

<string>

爲字符串類型提供支持和定義,包括單字節字符串(由char組成)的string和多字節字符串(由wchar_t組成)

<cctype>

單字節字符類別

<cwctype>

多字節字符類別

<cstring>

爲處理非空字節序列和內存塊提供函數。這不一樣於對應的標準C庫頭文件,幾個C樣式字符串的通常C庫函數被返回值爲const和非const的函數對替代了

<cwchar>

爲處理、執行I/O和轉換多字節字符序列提供函數,這不一樣於對應的標準C庫頭文件,幾個多字節C樣式字符串操做的通常C庫函數被返回值爲const和非const的函數對替代了。

<cstdlib>

爲把單字節字符串轉換爲數值、在多字節字符和多字節字符串之間轉換提供函數

C6. 定義容器類的模板的頭文件

頭文件

描        述

<vector>

定義vector序列模板,這是一個大小能夠從新設置的數組類型,比普通數組更安全、更靈活

<list>

定義list序列模板,這是一個序列的鏈表,經常在任意位置插入和刪除元素

<deque>

定義deque序列模板,支持在開始和結尾的高效插入和刪除操做

<queue>

爲隊列(先進先出)數據結構定義序列適配器queue和priority_queue

<stack>

爲堆棧(後進先出)數據結構定義序列適配器stack

<map>

map是一個關聯容器類型,容許根據鍵值是惟一的,且按照升序存儲。multimap相似於map,但鍵不是惟一的。

<set>

set是一個關聯容器類型,用於以升序方式存儲惟一值。multiset相似於set,可是值沒必要是惟一的。

<bitset>

爲固定長度的位序列定義bitset模板,它能夠看做固定長度的緊湊型bool數組

C7. 支持迭代器的頭文件

 

頭文件

描        述

<iterator>

給迭代器提供定義和支持

C8. 有關算法的頭文件

頭文件

描        述

<algorithm>

提供一組基於算法的函數,包括置換、排序、合併和搜索

<cstdlib>

聲明C標準庫函數bsearch()和qsort(),進行搜索和排序

<ciso646>

容許在代碼中使用and代替&&

C9. 有關數值操做的頭文件

頭文件

描        述

<complex>

支持複雜數值的定義和操做

<valarray>

支持數值矢量的操做

<numeric>

在數值序列上定義一組通常數學操做,例如accumulate和inner_product

<cmath>

這是C數學庫,其中還附加了重載函數,以支持C++約定

<cstdlib>

提供的函數能夠提取整數的絕對值,對整數進行取餘數操做

C10. 有關本地化的頭文件

頭文件

描        述

<locale>

提供的本地化包括字符類別、排序序列以及貨幣和日期表示。

<clocale>

對本地化提供C樣式支持

 

2.2.5名字空間的嵌套

在用戶聲明的名字空間中還能夠繼續嵌套其餘的名字空間,經過這種分層次的名字空間的結構能夠改善函數庫的代碼組織結構。具體代碼以下:

Namespace myFirstSpace

{

Int myVar = 10;

Namespace mySecondSpace

{

   int dlVar = 314;

   Int myVar = 100;//它會隱藏外圍名字空間聲明的變量。

}

}

只要須要,名字空間的嵌套能夠一直向下持續下去。在名字空間嵌套的時候,外圍名字空間聲明的變量可能會被裏面嵌套的名字空間聲明的同名變量隱藏。在使用嵌套名字空間成員的時候,有三種方式,具體狀況以下:

//第一種形式:限定修飾名稱形式

Int a = MyFirstSpace::mySecondSpace::dlVar;

//第二中形式:using聲明的形式:

Using myFirstSpace::mySecondSpace::dlVar;

Int a= dlVar;

//第三中形式:using指示符形式:

Using namespace myFirstSpace::mySecondSpace;

Int a = dlVar;

 

2.2.6未命名名字空間

使用未命名的名字空間,能夠定義文件做用域。具備文件做用域的名字空間只在定義它的文件中有效,在其餘文件中訪問不到該做用域。

未命名名字空間的定義格式以下:

----------------------------A.cpp--------------------------

Namespace

{

   Int a = 10;

   Void myFunction(int Para)

{

}

}

 

//使用未命名名字空間中的成員

Void main()

{

   myFunciton(a);//直接使用,不須要限定修飾。

}

    在使用未命名名字空間中的成員的時候,能夠直接使用,不須要限定修飾。未命名名字空間中的成員只能在定義它的文件中使用,在其餘文件中是沒法訪問的。

相關文章
相關標籤/搜索