C++關鍵字,你知道哪些呢?

1. C/C++中static的作用 (1)在C語言中,static主要定義全局靜態變量,定義局部靜態變量,定義靜態函數 一、 定義全局靜態變量 :在全局變量前面加上關鍵字static就變成了全局靜態變量,有以下特點: <1>在全局數據區內分配內存; <2>如果沒有初始化,其默認值為0; <3>該變量在本文件內從定義開始到文件結束可見; 二、定義局部靜態變量:在局部靜態變量前面加上關鍵字static就變成了靜態局部變量,有以下特點: <1>該變量在全局數據區分配內存; <2>如果不顯示初始化,那麼將被隱式初始化為0; <3>延長了局部變量的生命週期,它始終駐留在全局數據區,直到程序運行結束; <4>其作用域為局部作用域,當定義它的函數或語句塊結束時,其作用域隨之結束。 三、定義靜態函數:在函數的返回類型加上static關鍵字,有以下特點: <1>靜態函數只能在本源文件中使用 <2>在文件作用域中聲明的inline函數默認為static 說明:靜態函數只是一個普通的全局函數,只不過受static限制,它只能在文件所在的編譯單位內使用, 不能在其他編譯單位內使用。 (2)在C++語言中新增了兩種作用: 定義靜態數據成員 <1>可以實現多個對象之間的數據共享,它是類的所有對象的共享成員,它在內存中只佔一份空間,如果 改變它的值,則各對象中這個數據成員的值都被改變; <2>是在程序開始運行時被分配空間,到程序結束之後才釋放,只要類中指定了靜態數據成員,即使不定 義對象,也會為靜態數據成員分配空間; <3>可以被初始化,但是隻能在類體外進行初始化,若為對靜態數據成員賦初值,則編譯器會自動為其初 始化為0; <4>既可以通過對象名引用,也可以通過類名引用。

靜態數據成員有如下特點:

<1>內存分配:在程序的全局數據區分配; <2>初始化和定義:靜態數據成員定義時要分配空間,所以不能在類聲明中定義靜態成員函數。 <3>靜態成員函數和靜態數據成員都沒有this指針。 靜態成員函數 <1>靜態成員函數與類相聯繫,不與類的對象相聯繫。靜態成員函數不能訪問非靜態數據成員。原因很簡 單,非靜態數據成員屬於特定的類實例,主要用於對靜態數據成員的操作; <2>靜態成員函數和靜態數據成員一樣,他們都屬於類的靜態成員,而不是對象成員。

2. volatile { (1) 不會在兩個操作之間把volatile變量緩存在寄存器中。在多任務、中斷、甚至setjmp環境下,變量可能 被其他的程序改變,編譯器自己無法知道,volatile就是告訴編譯器這種情況,都會從變量的地址中讀 取數據,而不是從寄存器中獲取。 (2)不做常量合併、常量傳播等優化,所以像下面的代碼: volatile int i = 1; if (i > 0) ... if的條件不會當作無條件真。 (3) 對volatile變量的讀寫不會被優化掉。如果你對一個變量賦值但後面沒用到,編譯器常常可以省略那個 賦值操作,然而對Memory Mapped IO的處理是不能這樣優化的。 (4)volatile變量的幾個例子: <1>並行設備的硬件寄存器(如:狀態寄存器); <2>一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables); <3>多線程應用中被幾個任務共享的變量。

3. const的使用 1、常量使用const (1)const修飾變量 以下兩種定義形式在本質上是一樣的。含義是:const修飾的類型為TYPE的變量value是不可變的。 const int a; int const a;//都表示一個常整形數。 (2)將const改為外部連接,作用於擴大至全局,編譯時會分配內存,並且可以不進行初始化,僅僅作為聲明, 編譯器認為在程序其他地方進行了定義. extend const int ValueName = value; 2、指針使用const (1)指針本身是常量不可變 char* const a; /* const具有"左結合"性,即const修飾*,那麼不難理解,該句表示一個 指向整數的常指針,a指向的整數可以修改,但指針a不能修改。 (2)指針所指向的內容是常量不可變 int const *a; const int *a; /*根據"左結合"性,const修飾的是(*a),即是一個整數,所以這兩句表示 指針指向一個常整數。 (3)兩者都不可變 const char* const a; /*根據"左結合"性質,第一個const修飾(*),第二個const修飾(a),因此, 這句話表示一個指向常整數的常指針。 (4)還有其中區別方法,沿著*號劃一條線: 如果const位於*的左側,則const就是用來修飾指針所指向的變量,即指針指向為常量; 如果const位於*的右側,const就是修飾指針本身,即指針本身是常量。 3、函數使用const (1)const修飾函數參數 a.傳遞過來的參數在函數內不可以改變(無意義,因為Var本身就是形參) void function(const int Var); b.參數指針所指內容為常量不可變 void function(const char* Var); c.參數指針本身為常量不可變(也無意義,因為char* Var也是形參) void function(char* const Var); d.參數為引用,為了增加效率同時防止修改。修飾引用參數時: void function(const Class& Var); //引用參數在函數內不可以改變 void function(const TYPE& Var); //引用參數在函數內為常量不可變 這樣的一個const引用傳遞和最普通的函數按值傳遞的效果是一模一樣的,他禁止對引用的對象的一切修 改,唯一不同的是按值傳遞會先建立一個類對象的副本, 然後傳遞過去,而它直接傳遞地址,所以這種傳 遞比按值傳遞更有效.另外只有引用的const傳遞可以傳遞一個臨時對象,因為臨時對象都是const屬性, 且是不可見的,他短時間存在一個局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個傢伙。 (2)const 修飾函數返回值 const修飾函數返回值其實用的並不是很多,它的含義和const修飾普通變量以及指針的含義基本相同。 a.const int fun1() //這個其實無意義,因為參數返回本身就是賦值。 b. const int * fun2() //調用時 const int *pValue = fun2(); //我們可以把fun2()看作成一個變量,即指針內容不可變。 c.int* const fun3() //調用時 int * const pValue = fun2(); //我們可以把fun2()看作成一個變量,即指針本身不可變。 一般情況下,函數的返回值為某個對象時,如果將其聲明為const時,多用於操作符的重載。通常,不建議用 const修飾函數的返回值類型為某個對象或對某個對象引用的情況。原因如下:如果返回值為某個對象為const (const A test = A 實例)或某個對象的引用為const(const A& test = A實例) ,則返回值具有const屬 性,則返回實例只能訪問類A中的公有(保護)數據成員和const成員函數,並且不允許對其進行賦值操作,這 在一般情況下很少用到。 4、類相關const { (1)const修飾成員變量 const修飾類的成員函數,表示成員常量,不能被修改,同時它只能在初始化列表中賦值。 class A{ … const int nValue; //成員常量不能被修改 … A(int x): nValue(x) { } ; //只能在初始化列表中賦值 } (2)const修飾成員函數 const修飾類的成員函數,則該成員函數不能修改類中任何非const成員函數。一般寫在函數的最後來修飾。 class A{ … void function()const; //常成員函數, 它不改變對象的成員變量. //也不能調用類中任何非const成員函數。 } 對於const類對象/指針/引用,只能調用類的const成員函數,因此,const修飾成員函數的最重要作用就是 限制對於const對象的使用。 a. const成員函數不被允許修改它所在對象的任何一個數據成員。 b. const成員函數能夠訪問對象的const成員,而其他成員函數不可以。 (3)const修飾類對象/對象指針/對象引用 const修飾類對象表示該對象為常量對象,其中的任何成員都不能被修改。對於對象指針和對象引用也是一樣。 const修飾的對象,該對象的任何非const成員函數都不能被調用,因為任何非const成員函數會有修改成員變 量的企圖。 例如: class AAA { void func1(); void func2() const; } const AAA aObj; aObj.func1(); × aObj.func2(); 正確 const AAA* aObj = new AAA(); aObj-> func1(); × aObj-> func2(); 正確 }}4. extern C作用{ extern C 的主要作用就是為了能夠正確實現C++代碼調用其他C語言代碼。加上extern "C"後,會指示編譯器 這部分代碼按C語言的進行編譯,而不是C++的。由於C++支持函數重載,因此編譯器編譯函數的過程中會將函 數的參數類型也加到編譯後的代碼中,而不僅僅是函數名;而C語言並不支持函數重載,因此編譯C語言代碼 的函數時不會帶上函數的參數類型,一般只包括函數名。 這個功能十分有用處,因為在C++出現以前,很多代碼都是C語言寫的,而且很底層的庫也是C語言寫的,為了 更好的支持原來的C代碼和已經寫好的C語言庫,需要在C++中儘可能的支持C,而extern "C"就是其中的一個 策略。 這個功能主要用在下面的情況: (1)C++代碼調用C語言代碼; (2)在C++的頭文件中使用; (3)在多個人協同開發時,可能有的人比較擅長C語言,而有的人擅長C++,這樣的情況下也會有用到。} 5. Struct在C和C++中的區別 { C語言中: 是用戶自定義數據類型(UDT)。 是沒有權限設置的。 只能是一些變量的集合體,可以封裝數據卻不可以隱藏數據,而且成員不可以是函數。 C++語言中: 是抽象數據類型(ADT),支持成員函數的定義。 的成員的默認訪問說明符為public,class為private。 增加了訪問權限,且可以和類一樣有成員函數。 等同於class,只是class默認成員權限是private,而struct默認成員權限是public。 在標準C++中,struct和class有兩個區別: (1)struct中的成員默認是public的,class中的默認是private的。 (2)用模版時只能寫template <class>或template <typename>,不能寫template <struct>。 (3)如果沒有多態和虛擬繼承,在C++中,struct和class的存取效率完全相同!簡單的說就是,存取class 的data member和非virtual function效率和struct完全相同!不管該data member是定義在基類還是派生類的。 (4)如果不是為了和C兼容,C++中就不會有struct關鍵字。因此建議是:如果不需要與C兼容或傳遞參數給 C程序,不要在C++中用struct。 (5)注意class的data member在內存中的佈局可不一定是data member的申明次序。C++只保證處於同一個access section的data member按照申明次序排列。 (6)C++的struct可以當作class來用,他和C++中class的唯一的區別是,class中的成員默認是private,而 struct的成員默認為public。} /<struct>/<typename>/<class>

6. typename和class的區別 (1)在模板定義語法中關鍵字class與typename的作用完全一樣。 (2)typename另外一個作用為:使用嵌套依賴類型(nested depended name),如下所示: class MyArray { public: typedef int LengthType; ..... } template<class> void MyMethod( T myarr ) { typedef typename T::LengthType LengthType; LengthType length = myarr.GetLength; }/<class>

這個時候typename的作用就是告訴c++編譯器,typename後面的字符串為一個類型名稱,而不是成員函數或 者成員變量,這個時候如果前面沒有typename,編譯器沒有任何辦法知道 T::LengthType 是一個類型還是 一個成員名稱(靜態數據成員或者靜態函數),所以編譯不能夠通過。7. new/delete和malloc/free的區別 區別: 1. new/delete是C++裡才有的,而new/delete與malloc/free一個顯著的區別在於,new是建造一個對象, 並調用對象的構造函數來初始化對象,在所有的new操作過程中,總是分為兩步的:第一步是申請內存; 第二步則是調用構造函數初始化對象。在調用delete的時候,需要先調用析構函數,然後在銷燬堆內存; 而malloc和free只是分配的是一塊內存和釋放內存。 2. new/delete是操作符,就像"+","-";可以重載,重載之後就成為函數;而malloc/free是C中的函數。 3. new建立的對象可以用成員函數訪問,不用直接訪問它的地址空間;malloc分配的是一塊內存區域, 用指針訪問,可以在裡面移動指針。 4. malloc在申請內存的時候,必須要提供申請的長度,返回的指針是void*型,必須強轉才能成為需要的 類型;new出來的指針是帶有類型信息的。 5. 當new/delete在類中被重載的時候,可以自定義申請過程,比如記錄所申請內存的總長度,以及跟蹤 每個對象的指針。 6. C++默認的new/delete操作符內部,其實也調用了malloc/free這兩個函數。 7. new/delete是保留字,不需要頭文件支持;malloc/free需要頭文件庫函數支持。 相同: 1. 必須配對使用,配對使用不能理解為一個new/malloc就對應一個delete/free,而是指在作用域內, new/malloc所申請的內存,必須被有效釋放,否則將會導致內存洩漏(檢查方法:BoundsChecker)。 2. 都是申請內存,釋放內存,free和delete可以釋放NULL指針。 注意: 1. new/delete與malloc/free不能混合使用,因為在很多時候,混合使用後也沒有嚴重的後遺症,那是因 為在通常情況下,new操作符的確調用了malloc函數,所以free函數可以正常的釋放new出來的內存空間。 但這並不能保證所有的new操作符都是調用C++中new的原始操作符,因為在類中可以重載new這個操作符, 如果一但在operator=new()函數中調用了其它的申請函數的話,free將無法正常工作,或者說也將導致內 存洩漏。

竭力總結的C/C++關鍵字,你知道哪些呢?


分享到:


相關文章: