C++

發展歷史

C++語言發展大概可以分為三個階段：第一階段從80年代到1995年。這一階段C++語言基本上是傳統類型上的物件導向語言，並且憑藉著接近C語言的效率，在工業界使用的開發語言中佔據了相當大份額；第二階段從1995年到2000年，這一階段由於標準模板庫（STL）和後來的Boost等程式庫的出現，泛型程式設計在C++中佔據了越來越多的比重。當然，同時由於Java、C#等語言的出現和硬體價格的大規模下降，C++受到了一定的衝擊；第三階段從2000年至今，由於以Loki、MPL(Boost)等程式庫為代表的產生式程式設計和模板元程式設計的出現，C++出現了發展歷史上又一個新的高峰，這些新技術的出現以及和原有技術的融合，使C++已經成為當今主流程式設計語言中最複雜的一員。
比雅尼·史特勞斯特魯普（Stroustrup）工作起於1979年的C with Classes。這個構思起源於史特勞斯特魯普做博士論文時的一些程式撰寫經驗。他發現Simula具備很利於大型軟體開發的特點，但Simula的執行速度太慢，無法對現實需求發揮功效；BCPL雖快得多，但它過於低階的特性，使其不適於大型軟體的開發。當史特勞斯特魯普開始在貝爾實驗室工作時，他有分析UNIX核心關於分散式計算的問題。回想起他的博士論文經驗，史特勞斯特魯普開始為C語言增強一些類似Simula的特點。之所以選擇C，是因為它適於各種用途、快速和可移植性。除了C和Simula之外，同時也從其它語言中取得靈感，如ALGOL 68、Ada、CLU以及ML。
剛開始時，類別、衍生類別、儲存類型檢查、內聯和預設參數特性，都是透過Cfront引入C語言之中。
1983年，C with Classes改命名為C++（++是C語言中的增值運算子）。加入了新的特性，其中包括虛擬函式、函式名和運算子多載、參考、常數、使用者可控制的自由空間儲存區控制、改良的型別檢查，以及新的雙斜線（//）單行註解風格。
1985年，發布第一版《C++程式設計語言》，提供一個重點的語言參考，至此還不是官方標準。1985年10月出現了第一個商業化發布。
1989年，發布了Release 2.0。引入了多重繼承、抽象類別、靜態成員函式、常數成員函式，以及成員保護。1990年，出版了The Annotated C++ Reference Manual。這本書後來成為標準化的基礎。稍後還引入了模板、例外處理、命名空間、新的強制型別轉換，以及布林型別。
隨著C++語言的演變，也逐漸演化出相應的標準程式庫。最先加進C++標準函式庫的是串流I/O程式庫，其用以取代傳統的C函式，如printf和scanf。隨後所引入的程式庫中最重要的便是標準模板庫，簡稱STL。
多年後，一個聯合的ANSI-ISO委員會於1998年對C++標準化（ISO/IEC 14882：1998）。在官方釋出1998標準的若干年後，委員會處理缺陷報告，並於2003年發布一個C++標準的修正版本。2005年，一份名為Library Technical Report 1（簡稱TR1）的技術報告釋出。雖然還不是官方標準的一部分，不過它所提供的幾個擴展可望成為下一版C++標準的一部分。幾乎所有目前仍在維護的C++編譯器皆已支援TR1。
目前最新的C++標準是2017年12月發布的ISO/IEC 14882:2017，又稱C++17或C++1z。
雖然C++免專利，但標準檔案本身並不是免費的，儘管標準文件不是免費的，但是很容易從網路中取得，最簡單的就是C++標準文件之前的最後一次草稿版本，它與標準的差別幾乎只在於排版上。

C++名字的由來

C++這個名字是Rick Mascitti於1983年中所建議的，並於1983年12月首次使用。更早以前，尚在研究階段的發展中語言曾被稱為「new C」，之後是「C with Classes」。在電腦科學中，C++仍被稱為C語言的上層結構。它最後得名於C語言中的「++」運算子（其對變數的值進行遞增）。而且在共同的命名約定中，使用「+」以表示增強的程式。史特勞斯特魯普說：「這個名字象徵著源自於C語言變化的自然演進」。C+是一個和C/C++無關的早期程式語言。
Rick Mascitti在1992年被非正式地問起名字的由來，他表示這是在半開玩笑中說出的。他從沒想過C++會成為這門語言的正式名字。
有一個關於C++名字的笑話是，當你使用後綴++時，附加只發生在運算之後（因此，它應該是++C，而不是C++，這個笑話是說時下某些程式設計師還在以使用C的方式使用C++，這通常被一些權威著作認為是不正確的）。

標準程式庫

1998的C++標準分為兩個部分：核心語言和C++標準程式庫；後者包含了大部分標準模板庫和C標準程式庫的稍加修改版本。存在許多不屬於標準部分的C++程式庫，且使用外部連結，程式庫甚至可以用C撰寫。
C++標準程式庫充分吸收了C標準程式庫，並佐以少許的修改，使其與C++良好的運作。另一個大型的程式庫部分，是以標準模板庫（STL）為基礎，STL於1994年2月正式成為ANSI/ISO C++。它提供了實用的工具，如容器類（如：Array和Vector），疊代器（廣義指標）提供容器以類似陣列的存取方式，以及泛型演算法進行搜尋和排序的運算。此外還提供了(multi)map和(multi)set，它們都共用相似的成員函式。因此，以下成為可能，使用模板撰寫泛型演算法，它可以和任何容器或在任何以疊代器定義的序列上運作。如同C，使用#include指令包含標準表頭，即可存取程式庫裡的功能。C++提供69個標準表頭，其中19個不再贊成使用。
使用標準模板庫（例如：使用std::vector或std::string來取代C風格的陣列或字元陣列）有助於導向更安全和更靈活的軟體。
在STL在納入C++標準以前，是來自HP和後來的SGI的第三方程式庫，標準中並未稱之為「STL」，它只是標準庫中的一部分，但仍有許多人使用這個名稱，以別於其它的標準庫（輸入／輸出串流、國際化、診斷、C程式庫子集，等等）。
另外，如std::basic_string此類標準委員會添加的介面，有時也被誤認為STL；實際上它們並不存在於原始的SGI STL中，在標準化後SGI STL才從標準庫吸收加入其中。

C++中的特色

和C語言相比，C++引入了更多的特性，包括：複合型別（參照類型等）、const限定符和constexpr常數表達式、型別處理運算子（型別別名及auto和decltype等多種型別指示符）、C++標準庫（IO庫與多種容器類）與疊代器、動態記憶體與智慧型指標、函式重載、物件導向程式設計（如資料抽象化、成員函式、類作用域、建構函式與解構函式、靜態成員、存取控制與繼承、虛擬函式、抽象類與介面等）、拷貝控制、運算子多載、造型與函式風格的強制型別轉換、模板與泛型程式設計，以及異常處理、命名空間、多繼承與虛繼承、執行時型別辨識及巢狀類等。
和普遍認為的相反，C++不是第一個正式引入const關鍵字的語言。80年代早期，Bjarne Stroustrup和Dennis Retchie討論之後提供了在C語言中readonly/writeonly的實現機制，並在帶類的C中取得了一定經驗。關鍵字const正式引入C語言是在ANSI C89。這早於第一個C++國際標準近十年，但此時const已被C++實現普遍採用。
C++在某些案例中（見下「與C不相容之處」），進行比C還要多的類型檢查。
以「//」起始作為註解起源自C的前身BCPL，而後被重新引入到C++。
C++的一些特性，C不久之後也採用了，包括在for迴圈的括號中聲明，C++風格的註解（使用//符號，和inline，雖然C99定義的inline關鍵字與C++的定義不相容。不過，C99也引入了不存在於C++的特性，如：可變參數巨集，和以陣列作為參數的較佳處理；某些C++編譯器可能實作若干特性，以作為擴展，但其餘部分並不符合現存的C++特性）
一個常見的混淆其實只是一個微妙的術語問題：由於它的演化來自C，在C++中的術語物件和C語言一樣是意味著記憶體區域，而不是類別的實體，在其它絕大多數的物件導向語言也是如此。舉例來說，在C和C++中，語句int i;定義一個int型別的物件，這就是變數的值i將在指派時，所存入的記憶體區域。

C++語言中的const關鍵字

const是一個C和C++語言的關鍵字，意思是宣告一個常數(不能改變的變數)，即唯讀。使用const在一定程度上可以提高程式的安全性和可靠性，也便於實現對此進行最佳化（如把唯讀物件放入ROM中）。const作為型別限定符，是型別的一部分。
以下是和C語言相容的用法：
1 int m = 1, n = 2;   // int 类型的对象2 const int a = 3;    // const int 类型的对象3 int const b = 4;    //同上4 const int *p        //指向 const int 类型对象的指针5 int const *q;       //同上6 int *const x;       //指向 int 类型对象的 const 指针；注意 const 的位置7 const int *const r; //指向 const int 类型对象的 const 指针8 int const *const t; //同上
但是，const在C++中有更強大的特性。它允許在編譯時確定作為真正的常數表達式。例如，
1 const int max_len = 42;2 int a[max_len];
此前C語言並不支援這樣的用法，直到C99允許用變數作為陣列長度（需要注意的是C99中的VLA支援執行期確定陣列長度，但C++從未支援）。此外，C++中，命名空間作用域的const物件的名稱隱含內部連結。這意味著直接在標頭檔里定義const物件被多個原始檔包含時，也不會重定義。
在C++11及之後的C++標準中，推薦使用擁有更嚴格語意的constexpr限定符來表示一個可以出現在常數表達式中的變數。const可區分為頂層const(top-level const)和底層const(low-level const)。
實際上，在語意表達方面，const更多表示為「唯讀」，constexpr才表示編譯期常數。

與C不相容之處

C++有時被認為是C的超集（superset），但這並不嚴謹。
各個版本的ISO/IEC 14882的附錄C中都指出了C++和ISO C的一些不相容之處。
大部分的C程式碼可以很輕易的在C++中正確編譯，但仍有少數差異，導致某些有效的C程式碼在C++中失效，或者在C++中有不同的行為。
最常見的差異之一是，C允許從void*隱式轉換到其它的指標型別，但C++不允許。下列是有效的C程式碼：
1 // 从void *隐式转换为int *2 int *i = malloc(sizeof(int) * 5);
但要使其在C和C++兩者皆能運作，就需要使用顯式轉換：
1 int *i = (int *)malloc(sizeof(int) * 5);
另一個常見的可移植問題是，C++定義了很多的新關鍵字，如new和class，它們在C程式中，是可以作為識別字（例：變數名）的。
C99去除了一些不相容之處，也新增了一些C++的特性，如//注釋，以及在程式碼中混合使用。不過C99也納入幾個和C++衝突的新特性（如：可變長陣列、原生複數型別和複合逐字常數），而C++11已經加入了相容C99預處理器的特性。
由於C++函式和C函式通常具有不同的名字修飾和呼叫約定，所有在C++中呼叫的C函式，須放在extern "C" { /* C函数声明 */ }之內。

C++的Hello World程式

下面這個程式顯示「Hello, world!」然後結束執行：
1 #include <iostream>2 int main() {3     std::cout << "Hello, world!" << std::endl;4     return 0;5 }
這裡也可以使用using指令以避免再次聲明std::——
1 #include <iostream>2 using namespace std;3 int main() {4     cout << "Hello, world!" << endl;5     return 0;6 }
你可以用「\n」代替以上程式碼裡的「endl」，不過必須用在句子的後端。請不要把斜槓（/）和反斜槓（\）混淆。
1 std::cout << "Hello, world!\n";
但需要知道的是， std::endl 不僅僅會在某個輸出流中插入換行字元，還將執行輸出流的 flush() 函式（即重新整理緩衝區），而'\n'則不會。

根據ISO C++的規定，全域main函式必須返回int。
以下兩種形式是合法的：
1 int main() {2     // ...3 }
1 int main(int argc, char *argv[]) {2     // ...3 }
不過，在一些編譯器（例如Visual C++）上，
1 void main() {2     // ...3 }
也是合法的。永遠不要這樣寫，因為這樣的寫法沒有相容性。

預處理器

C++主要有三個編譯階段：預處理、轉譯成目的碼和連結（最後的兩個階段一般才視為真正的「編譯」）。在第一階段，預處理，會將預處理器指令替換成原始碼，然後送到下一個編譯階段。

模板

模板（Template）指C++程式語言中的函式模板（function template）與類別模板（class template），這種觀念是取材自Simula的泛型程式設計。它採用typename和class兩個關鍵字，來標識模板類別的型別參數。C++11和C++14分別引入了型別別名模板和變數模板。

類別與物件

在物件導向物件程式設計術語中，物件（object）是資料（data）和處理資料的指令（instructions）的聯合（association）。類比（simulate）實際世界（real-world），物件有三種特質（characteristics）：狀態（State）、行為（Behavior）、同一性身分，並且使用訊息（message）來引發彼此的互動。類別（class）為物件的藍圖或工廠，定義了物件的抽象特質，包括物件的屬性特質和物件的行為特質，屬性的值即是物件的狀態，行為即是物件能夠做的事。
C++為類別構成式物件導向程式設計語言（class-based object-oriented programming language），類別概念具現化（reification）地作為二等公民（second-class citizen）出現在C++語言當中，在語法中明確地使用類別來做到資料抽象化、封裝、模組化、繼承、子型別多型、物件狀態的自動初始化。C++中，一個類別即為一個型別，加上封裝，一個類別即為一個抽象資料型別（Abstract Data Type，ADT），繼承、多型、模板都加強了類別的可抽象性。在C++可以使用class或struct這兩個關鍵字宣告類別（class），而使用new運算子實體化類別產生的實體（instance）即為物件，是一等公民。C/C++以資料成員（data member）表達屬性，以成員函式（member function）表達行為。
聲明一個Car class：
1 class Car {2 private:3     int isRunning;4 public:5     Run();6 };
但是仍然需要注意，嚴格來說，C++中物件的概念和C的對應概念接近，表示的是具有特定型別的儲存，而非物件導向意義上的「物件」：一個物件不一定是類型別的。此外，C++意義上的「實體」僅指模板實體化的結果，而並不指物件。作為對比，Java的「物件」和「實體」的概念和這裡的使用一致。

分析和處理C++原始程式碼

C/Java/C#都可以用某種 LR 剖析器（或其變形）分析文法，但C++是個著名的例外：請看下面的程式碼。
1 #include <vector>2 #include <string>3 std::vector< std::vector<std::string> >table1;4 std::vector<std::vector<std::string>>table2;
上面的table1顯然是一個字串的二維陣列，而table2則未必能通過編譯：如果嚴格遵循LR分析過程，串 >> 會被解釋為右移運算子而非兩個代表模板參數列結束的右尖括號，因此出現編譯錯誤，必須以table1的方式用空格區分。(在C++11發布之後，特別規定了當處理模板時，>>被優先視為兩個>，所以table1和table2均可通過編譯.)