C++語法規則積累

面向對象程序設計,是針對開發較大規模的程序而提出來的,目的是提高軟件開發的效率。下面是小編整理的關於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++ 函數探幽:

內聯函數:inline int function(…), 內聯函數可以替代宏代碼片段,在編譯時將函數體直接替代函數被調用的地方,這樣就減少了普通函數被調用時 的開銷(壓棧,跳轉等),但是內聯函數本質上還是一個函數,不同於宏代碼片段。內聯函數聲明符inline 必須要和函數定義結合在一起,不能放在聲明處,否則編譯器忽略內聯請求。 雖然內聯函數省時省空間,但是編譯器不一定準許函數的內聯請求,當C++編譯器不允許內聯請求時會將內聯函數當做普通函數處理。

默認參數: C++中可以在函數聲明時爲參數提供一個默認值,當函數調用時沒有提供這個參數的值,編譯器會自動用默認值代替。但是在函數定義時就不在指定默認參數值。默認參數有如下規則:

只有參數列表後面的部分參數纔可以提供默認參數值,一但在一個函數調用中開始使用默認參數,那麼這個參數後的所有參數都必須使用默認參數,因此從開始使用默認參數的使用開始都後面的參數都要提供默認參數,否則編譯器將報錯。總之,在函數聲明時,如果一個參數開始提供默認參數,那麼後面的所有參數都要提供默認參數;在調用函數時,如果開始省略參數,那麼後面所有參數都使用默認參數。

函數佔位參數:佔位參數是在函數定義時只有類型聲明,沒有參數名聲明的參數。一般情況下函數體內部無法使用佔位參數。但是在調用時必須提供完整的參數個數。可以給佔位參數提供默認參數。意義:爲函數的後續版本的擴展埋下伏筆;兼容C語言中的不規範寫法。

函數重載:簡單來說函數重載就是用同一個函數名來定義不同的函數。那編譯器是如何區分這些函數的呢?事實上,編譯器是通過參數列表來區分重載了的函數。即重載函數擁有不同的參數列表。不同的參數列表包括參數個數不同、參數類型不同、參數順序不同,即滿足上述三個條件之一就能構成重載函數。函數重載在構造函數中是非常有用的。

當函數默認參數遇上函數重載會發生什麼神奇的情況?假設這樣的情況:程序當中定義兩個重載函數,其中一個函數有一個默認參數,在主函數調用這個函數。能不能編譯過呢?

經過編譯器的驗證,當函數默認參數遇上函數重載,編譯時沒有問題的,但是調用時會發生函數二義性的錯誤。因此在程序中不能同時使用函數默認參數和函數重載。

  編譯器調用重載函數的準則:

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++ 新關鍵字:

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 修飾符

v 在C++中可以定義靜態成員變量和靜態成員函數

v 靜態成員屬於整個類所有,不需要依賴任何對象

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

v 可以通過對象名訪問public靜態成員

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

定義靜態成員變量:

à在定義類時通過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 成員在子類中仍然存在,但是卻無法訪問。