C++關鍵字總結【新手必學】



const 關鍵字——常量
const 與define
define是預編譯器的編譯指令,它從C語言兼容下來,工做方式與文本編輯器中的全局搜索和替換類似。define定義的常量的意義在它開始的地方持續到文件結束,在預編譯階段,預編譯器已經將全部define刪除,並展開全部的宏定義。它單純只作文本替換,沒有類型安全檢查,define命令會很容易引入錯誤,而且這種錯誤很難發覺,所以C++中用const取代define預編譯指令。另外不少人在學習Python的過程當中,每每由於沒有好的教程或者沒人指導從而致使本身容易放棄,爲此我建了個C++交流.裙 :九起久傘吧起傘留傘(數字的諧音)轉換下能夠找到了,裏面有最新C++教程項目可拿,不懂的問題多跟裏面的人交流,都會解決哦!編程

#define SIGMOID(x) (1/(1+exp(-x)))
result = SIGMOID(a+b);//沒有正確添加括號,會致使錯誤結果
result = SIGMOID((a+b));//正確

頭文件裏的const
const默認是內部連接,若是它被放在頭文件中,目的是爲了讓全部包含它的編譯單元能使用這個值,並且是僅讓包含頭文件的編譯單元可見。定義一個const時,必須初始化,除非用extern作出了外部引用。一般,C++編譯器不會爲const變量分配空間,但extern關鍵字會強制編譯器爲const變量分配存儲空間。由於extern爲外部連接,爲了其餘的編譯單元都能引用到const變量。變量必需要有存儲空間。
注:因爲編譯器不能避免爲const分配內存,因此const定義必須默認內部連接。在C++中,const常量是否被分配空間依賴於它如何被使用:對於基本數據類型的常量,編譯器會把它放到目標文件的符號表中而不分配存儲空間,而自定義的const對象則須要分配存儲空間(大對象)。還有一些狀況下也須要分配存儲空間,例如強制聲明爲extern或取一個const的地址等操做。緩存

const關鍵字與多線程安全
可重入是併發安全的保障,一個可重入的函數(函數沒有執行完成,因爲外部因素或內部調用,又一次進入函數執行)在多線程的環境下能夠放心使用。而爲了保證一個函數是可重入的,它必須使用任何(局部)靜態或非const全局變量。同時,不能返回任何(局部)靜態或非const全局變量的指針。安全

類中的const
在類中定義的非靜態const變量,這個類的不一樣的對象能夠含有一個不一樣的值。const的初始化在類的構造函數的初始化列表中。網絡

static const——編譯期間類裏的專屬常量
static意味着「無論類的對象被建立多少次,都只有一個實例」。必須在static const定義的地方對它初始化。C++用它來代替enum(枚舉型),來指示對象的共同屬性。它是爲整個類服務,而不是某個對象,因此它不能使用this指針(this指針是對成員函數調用時用來指示調用對象的),也不能在複製構造函數中被複制。若是你取某個類的專屬常量的地址或編譯器堅持要看到一個定義式,則用域名解析符定義一下多線程

//GamePlayer.h中
class GamePlayer{
private:
static const int NumTurns = 5;
int scores[NumTurns];
};
//GamePlayer.cpp中
const int GamePlayer::NumTurns;//NumTurns在class聲明中已經初始化,所以這裏再也不設初值
const對象和成員函數
不修改數據成員的任何函數都應該聲明爲const,這樣它能夠和const對象一塊兒使用。
按位const:對象中的每一個字節都不能變。
按邏輯const:能夠以成員爲單位改變。併發

兩種實現按邏輯const的方法
一種是取this指針,並把它強制轉換成指向當前類型對象的指針,具體來講就是講將this強制轉換成普通指針。
另外一種是使用關鍵字mutable,以指定一個特定的數據成員能夠在一個const對象中被改變。編輯器

static關鍵字——靜態區、內部連接
static關鍵字有兩個做用,一個讓變量存在靜態區,另外一個是讓錯誤限制在一個源文件內。讓局部變量聲明成static使局部變量存儲在靜態區,從而在程序的整個生命期都存在。同時,當static做用於全局變量時,該全局變量變爲內部連接,它的意思是「在文件的外部不可使用這個名字」,從而使錯誤局部化。
static全局變量與全局變量的區別是靜態變量只初始化一次,防止在其餘文件中被引用;static局部變量與普通局部變量的區別除了值在啓動程序時初始化一次外,就是它的值在程序的整個週期內都存在,兩次函數調用期間,它的值保持不變;局部靜態變量在函數調用之間的值保持不變,根據這個特性,能夠用於記錄函數調用或類建立的一些信息。
static函數與普通函數的區別是static函數在內存中只有一份,而普通函數在每次被調用都維持一份拷貝。函數

extern關鍵字——外部變量
extern關鍵字用來聲明另外一個文件中的全局變量。因此extern和static是矛盾的,不能同時使用。
extern 「C」關鍵字
C++編譯器將extern 「C」中的代碼單作C語言代碼處理。extern C大括號所包圍的範圍中,C++的名稱修飾機制不起做用,對於Visual C++,直接在變量名和函數名前加」_」。但對於Linux下的GCC,extern 「C」後面的符號都是修飾後符號。
注:在C語言中不支持使用extern關鍵字
這裏列舉我平時編程時遇到的問題及處理方案
在我用vs2012調用C語言寫的庫時,出現「error LNK2019: 沒法解析的外部符號 clGetPlatformIDs「的錯誤。
緣由一般是沒有包含相應的lib,也就是說連接器沒搜索到相應lib中的clGetPlatformIDs目標模塊,基於這種狀況,我思考會不會是這個函數在頭文件中是C語言函數的聲明與定義,可是我又在C++代碼中包含該頭文件,致使其採用C++的名稱修飾機制而沒法與C語言庫中符號連接。因此對於C++調用C庫,須要添加extern 「C」關鍵字聲明。
一般的作法是定義宏學習

#ifdef __cplusplus
extern C" {
#endif優化

cl_int clGetPlatformIDs(...);

#ifdef _cplusplus
}
#endif
可是若是這個C源碼已經編譯成庫,可是模塊的頭文件中沒有包含extern 「C」,則在C++文件中,須要添加

extern "C"{
#include "cl.h"
這至關於在cl.h頭文件中全部的聲明都添加了extern。

連接與const、static、extern——內存分配與讀寫
無連接性:在代碼塊中的局部變量(包括static局部變量)
外部連接:函數以外定義的全部變量(除了const變量)和函數默認爲外部連接性。在定義時使用extern關鍵字顯式指定標識符具備外部連接。也就是說在多個文件程序中,能夠在文件而且只能在一個文件中定義全局變量,其餘文件要使用該變量,要在變量前添加extern關鍵字。當有extern時,只是告知編譯器存在這個變量,編譯器並不爲該變量分配存儲空間,即真正的聲明;若沒有extern,則在聲明的同時,編譯器也爲該變量分配存儲空間。
內部連接:全局static變量和const變量爲內部連接,爲了使const具備外部連接以便讓另一個文件能夠對它引用,必須在當前文件裏明確把它定義爲extern並初始化。
應使用連接性爲外部的多文件程序的不一樣文件中共享數據,而使用連接性爲內部的靜態變量在同一文件中的多個函數間共享數據

volatile關鍵字
告訴編譯器「該變量不知道什麼時候回改變「,防止編譯器依據變量的穩定性(短時間內值不變)做任何優化。
volatile關鍵字與多度優化
在多線程環境下,即便合理地使用了鎖,也不必定能保證線程安全。

x=y=0
Thread1 Thread2
x=1 y=1
r1=y r2=x
因爲CPU的動態調度或編譯器的優化,執行程序時,有可能交換兩條絕不相干的相鄰指令的順序,致使r1=r2=0的狀況的發生。而volatile關鍵字能夠試圖阻止優化。
(1)阻止編譯器爲了提升速度將一個變量緩存到寄存器而不寫回。也就是說防止編譯器根據變量的穩定性做任何優化,假設要讀一個硬件中的寄存器,將使用這個關鍵字。不管什麼時候須要volatile變量的值,編譯器都要硬着頭皮頭讀,即便該行以前剛剛讀過。
(2)阻止編譯器調整volatile變量的指令順序。(這一步其實只能阻止編譯器的優化換序,並不能 阻止CPU動態調度換序)
注:阻止CPU亂序執行的惟一辦法是調用CPU提供barrier指令;

關鍵字restrict
關鍵字restrict只用於限定指針;該關鍵字用於告知編譯器,全部修改該指針所指向內容的操做所有都是基於(base on)該指針的,即不存在其它進行修改操做的途徑;這樣的後果是幫助編譯器進行更好的代碼優化,生成更有效率的彙編代碼。
最後注意一點,restrict是C99中定義的關鍵字,C++目前並未引入;在GCC可經過使用參數」 -std=c99」
來開啓對C99的支持

enum枚舉類型
本質上,enum是一個int型,但C++不容許enum到int的隱式轉換。枚舉的類型名也是可選的。enum{ a,b,c}choice;能夠當即定義一個enum實例。一個類中的枚舉在編譯期間分配值,不佔用對象的內存空間。但一般優先選擇static const而儘可能不是用enum。枚舉常量的缺點是:它的隱含數據類型是整數,其最大值有限,且不能表示浮點數

register變量
關鍵字register只是告訴編譯器「儘量快地訪問該變量」dawn並不能保證將變量放置在寄存器中。同時,register有許多限制,好比不能獲取register變量的地址,不能將其聲明爲全局或靜態變量,由於register變量沒有內存地址。所以,最好避免使用。
————————————————
另外不少人在學習Python的過程當中,每每由於沒有好的教程或者沒人指導從而致使本身容易放棄,爲此我建了個C++交流.裙 :九起久傘吧起傘留傘(數字的諧音)轉換下能夠找到了,裏面有最新C++教程項目可拿,不懂的問題多跟裏面的人交流,都會解決哦!

以上,有些內容轉自網絡,若有侵權,請聯繫博主改正。

相關文章
相關標籤/搜索