1. 程式人生 > >C++ 語法規則

C++ 語法規則

C++ 中的布林型別:布林型別只佔用一個bit ,但是如果連續定義多個布林型別時,編譯器可能會多個布林型別定義在一起。true  編譯器用1來表示。false  編譯器用0來表示。

將一個其他型別的資料賦給布林型別變數:C++編譯器會將所有的非0的值轉換為true(1),將0 轉化為false(0)。

三木運算子   ? :    :將一個三目運算子作為左值: (a>b?a:b) = 3 C語言不支援(三目運算子返回一個值),但在C++中支援(三目元算符返回變數)。    但是如果可能的返回值有一個是常量值,那麼它就不能作為左值使用,如(a>b?1:b) = 3  非法。

引用:

C++中的引用:

一個已經定義的變數的別名。 Type var , Type & name = var; 普通引用在宣告時必須用其他的變數進行初始化。引用作為函式引數宣告時不進行初始化。

const 修飾引用:const 使引用擁有隻讀屬性,但是變數本身還是原來的屬性。

當使用常量對const 引用進行初始化時,編譯器會給常量分配空間,並將引用名命名為這段空間的別名。不能給普通引用賦值為常量,但是可以給常引用賦值為常量。此時常引用是隻讀的,除了在定義時,不能給它賦值。因此用一個常引用可以構成一個只讀的變數,如 const int & a = 10  a是一個只讀變數。

引用在C++ 的內部實現是一個常指標:

type & name   ßàtype* const name。因此引用擁有一個4位元組的空間。

引用作為函式返回值:返回區域性變數的引用時,引用不能作為左值,也不能用它初始化其他引用,但是如果引用時靜態的或者全域性變數的引用時就可以。

C++ 函式探幽:

  1. 行內函數:inline int function(…),  行內函數可以替代巨集程式碼片段,在編譯時將函式體直接替代函式被呼叫的地方,這樣就減少了普通函式被呼叫時 的開銷(壓棧,跳轉等),但是行內函數本質上還是一個函式,不同於巨集程式碼片段。行內函數宣告符inline 必須要和函式定義結合在一起,不能放在宣告處,否則編譯器忽略內聯請求。 雖然行內函數省時省空間,但是編譯器不一定準許函式的內聯請求,當C++編譯器不允許內聯請求時會將行內函數當做普通函式處理。 
  2. 預設引數: C++中可以在函式宣告時為引數提供一個預設值,當函式呼叫時沒有提供這個引數的值,編譯器會自動用預設值代替。但是在函式定義時就不在指定預設引數值。預設引數有如下規則:

只有引數列表後面的部分引數才可以提供預設引數值,一但在一個函式呼叫中開始使用預設引數,那麼這個引數後的所有引數都必須使用預設引數,因此從開始使用預設引數的使用開始都後面的引數都要提供預設引數,否則編譯器將報錯。總之,在函式宣告時,如果一個引數開始提供預設引數,那麼後面的所有引數都要提供預設引數;在呼叫函式時,如果開始省略引數,那麼後面所有引數都使用預設引數。

  1. 函式佔位引數:佔位引數是在函式定義時只有型別宣告,沒有引數名宣告的引數。一般情況下函式體內部無法使用佔位引數。但是在呼叫時必須提供完整的引數個數。可以給佔位引數提供預設引數。意義:為函式的後續版本的擴充套件埋下伏筆;相容C語言中的不規範寫法。
  2. 函式過載:簡單來說函式過載就是用同一個函式名來定義不同的函式。那編譯器是如何區分這些函式的呢?事實上,編譯器是通過引數列表來區分過載了的函式。即過載函式擁有不同的引數列表。不同的引數列表包括引數個數不同、引數型別不同、引數順序不同,即滿足上述三個條件之一就能構成過載函式。函式過載在建構函式中是非常有用的。

當函式預設引數遇上函式過載會發生什麼神奇的情況?假設這樣的情況:程式當中定義兩個過載函式,其中一個函式有一個預設引數,在主函式呼叫這個函式。能不能編譯過呢?

經過編譯器的驗證,當函式預設引數遇上函式過載,編譯時沒有問題的,但是呼叫時會發生函式二義性的錯誤。因此在程式中不能同時使用函式預設引數和函式過載。

編譯器呼叫過載函式的準則:

l  將所有的同名函式作為候選者

l  嘗試尋找可行的候選函式

& 精確匹配實參

& 通過預設引數匹配實參

& 通過預設型別轉換匹配實參

l  匹配失敗

& 最終找到的可行候選函式不唯一,出現二義性,編譯失敗

& 無法匹配所有候選者,函式未定義,編譯失敗

注意:過載函式與返回值型別沒有半毛錢關係。

當過載函式賦值給函式指標時發生:

1).根據過載規則挑選與函式指標引數列表一致的候選者

2).嚴格匹匹配候選者的函式型別與函式指標的函式型別

只有上述兩個不步驟都成功時才能匹配成功,成功呼叫正確的函式。

C 與 C++ 互相呼叫:可以使用extern關鍵字強制讓C++編譯器對程式碼使用C的方式進行編譯。如 extern  “C” { content}

使用如下處理統一處理: __cplusplus 是C++編譯器內建的標準巨集定義,讓C程式碼既可以通過C編譯器的編譯,也可以在C++ 編譯器中以C方式編譯。

              #ifdef __cplusplus

              extern  “C”{

              #endif

              //函式宣告或者函式定義

              #ifdef  __cplusplus

              }

              #endif

C++ 新關鍵字:

  1. new  和delete  動態記憶體分配和釋放

變數申請                                     陣列申請

type* pointer = new type;        type* pointer = new type[N];         //申請記憶體

//…….                                      //…….                                           //使用記憶體

delete  pointer                     delete[]  pointer                              //釋放記憶體

可以看出,new出來的記憶體空間不像普通變數那樣有一個別名,只有一個地址賦給指標,訪問都必須通過指標。

new 與 malloc 函式的區別:

l  malloc 是C庫提供的函式,new關鍵字是C++ 的一部分

l  new 以具體型別為單位進行記憶體分配,malloc只能以位元組為單位進行記憶體分配

l  new 在申請單個型別變數時可以進行初始化,malloc 不具備初始化的特性

名稱空間(namespace)

C語言中所有的全域性識別符號共享同一個作用域:全域性作用域,C++將全域性作用域分成不同的部分,每個部分就是一名稱空間,不同名稱空間裡的識別符號可以同名而不會發生衝突,並且名稱空間可以巢狀。值得注意的是全域性作用域也叫預設名稱空間。

名稱空間的使用:

l  使用整個名稱空間:using   namespace  name;

l  使用名稱空間中的變數: using  name  ::variable

l  使用預設名稱空間  :: variable

類的靜態成員:靜態成員函式+靜態成員變數

類的靜態成員變數:儲存在全域性資料區、不依賴於任何一個物件的類成員變數。

語法規則:type  classname  ::varname

類的靜態成員函式:

語法規則 : 加上static 修飾符

C++中可以定義靜態成員變數和靜態成員函式

靜態成員屬於整個類所有,不需要依賴任何物件

可以通過類名直接訪問public靜態成員

可以通過物件名訪問public靜態成員

靜態成員函式可以直接訪問靜態成員變數

定義靜態成員變數:

à在定義類時通過static 修飾成員成員變數可以將變數定義成靜態成員變數

à靜態成員變數不依賴任何物件,需要在類的定義外面單獨分配空間:

type Classname::Varname;

靜態成員函式的定義:

è 在定義時直接通過static 關鍵字修飾,其他的部分與普通的成員函式定義相同。

注意:C++ 類物件中的成員函式和成員變數是分開儲存的

à成員變數:普通的成員變數儲存在物件中,跟struct 變數有相同的記憶體分佈和位元組對齊方式;靜態成員變數:儲存在全域性資料區;

à成員函式:儲存於程式碼段中

靜態成員函式和普通成員函式的區別:

l  靜態成員函式不包含指向具體物件的指標 this, 但是普通成員函式包含有一個指向物件本身的指標:this 指標

繼承:子類擁有父類的所有成員函式和成員變數、子類就是一種特殊的父類、子類物件可以當做父類物件使用、子類擁有父類沒有的方法。

C++中的訪問級別與繼承:

public 繼承:父類成員在子類中保持原有的訪問級別

       class child :pubic parent

private繼承:父類成員在子類中是private訪問級別

class child : parent ßàclass child :private parent

C++預設是私有繼承:子類從父類繼承得到的成員預設是私有的。

因為父類的private 成員在子類中不能被子類訪問,因此出現一個新的訪問級別:protected

類的protected 成員:

l  Protected 成員可以在子類中被訪問,但不能再外界被訪問

l  Protected 成員的訪問許可權介於public 和private 這兩個級別之間

類成員訪問級別設定的原則:

l  需要被外界訪問的直接設定為public

l  只能在當前類中訪問的成員設定為private

l  只能在當前類和子類中訪問的成員設定為protected

注:private 成員在子類中仍然存在,但是卻無法訪問。

操作符過載:操作符過載的本質是通過函式過載實現。通過operator 關鍵字擴充套件操作符 :type operator character(…)  {…}