C++程序设计语言

**C++** 是一種被廣泛使用的電腦程式設計語言。它是一種通用程式設計語言，支援多重程式設計範式，例如過程化程式設計、物件導向程式設計、泛型程式設計和函數式程式設計等。

比雅尼・斯特勞斯特魯普博士在貝爾實驗室工作期間在 20 世紀 80 年代發明並實現了 C++。起初，這種語言被稱作「C with Classes」（「包含『類』的 C 語言」），作為 C 語言的增強版出現。隨後，C++ 不斷增加新特性。虛擬函式、運算子多載、多繼承、標準模板庫、例外處理、執行時型別資訊、命名空間等概念逐漸納入標準草案。1998 年，國際標準組織頒布了 C++ 程式設計語言的第一個國際標準 ISO/IEC 14882:1998，目前最新標準為 ISO/IEC 14882:2020。ISO/IEC 14882 通稱 ISO C++。ISO C++ 包含了主要包含了核心語言和標準庫的規則。儘管從核心語言到標準庫都有顯著不同，ISO C++ 直接正式（normative）參照了 ISO/IEC 9899（通稱 ISO C），且 ISO C++ 標準庫的一部分和 ISO C 的標準庫的 API 完全相同，另有很小一部分和 C 標準庫略有差異（例如，`strcat` 等函式提供對 `const` 型別的多載）。這使得 C 和 C++ 的標準庫實現常常被一併提供，在核心語言規則很大一部分相容的情況下，進一步確保使用者通常較容易把符合 ISO C 的源程式不經修改或經極少修改直接作為 C++ 源程式使用，也是 C++ 語言繼 C 語言之後流行的一個重要原因。

作為廣泛被使用的工業語言，C++ 存在多個流行的成熟實現：GCC、基於 LLVM 的 Clang 以及 Visual C++ 等。這些實現同時也是成熟的 C 語言實現，但對 C 語言的支援程度不一（例如，VC++ 對 ANSI C89 之後的標準支援較不完善）。大多數流行的實現包含了編譯器和 C++ 部分標準庫的實現。編譯器直接提供核心語言規則的實現，而庫提供 ISO C++ 標準庫的實現。這些實現中，庫可能同時包含和 ISO C 標準庫的共享實現（如 VC++ 的 msvcrt）；而另一些實現的 ISO C 標準庫則是單獨於編譯器專案之外提供的，如 glibc 和 musl。C++ 標準庫的實現也可能支援多種編譯器，如 GCC 的 libstdc++ 庫支援 GCC 的 g++ 和 LLVM Clang 的 clang++。這些不同的豐富組合使市面上的 C++ 環境具有許多細節上的實現差異，因而遵循 ISO C++ 這樣的權威標準對維持可移植性顯得更加重要。現今討論的 C++ 語言，除非另行指明，通常均指 ISO C++ 規則定義的 C++ 語言（雖然因為實現的差異，可能不一定是最新的正式版本）。

值得注意，和流行的誤解不同，ISO C 和 ISO C++ 都從未明確要求源程式被_編譯（compile）_ ，而僅要求_翻譯（translate）_ ，因此 C 和 C++ 並不是所謂的_編譯型_語言。技術上，實現 C 和 C++ 程式的單位是翻譯單元（translation unit）。作為對比，Java 語言規範中就明確要求 Java 程式被編譯實現，明確存在編譯單元（compilation unit）。實際上 C 和 C++ 也存在 REPL 形式的直譯器實現，如 CINT 和 Cling。但因為傳統上 C 和 C++ 多以編譯器實現，習慣上仍有一些混用，甚至至今仍出現在 ISO C++ 某節標準庫條款的標題 （頁面存檔備份，存於網際網路檔案館）上。

傳統上，C++ 語言被視為和 C 語言實現效能相近的語言，強調執行時的高效。根據《C++ 編程思想》（_Thinking in C++_）一書，C++ 與 C 的代碼執行效率往往相差在 ±5% 之間。

## 發展歷史

C++ 語言發展大概可以分為三個階段：第一階段從 80 年代到 1995 年。這一階段 C++ 語言基本上是傳統類型上的物件導向語言，並且憑藉著接近 C 語言的效率，在工業界使用的開發語言中佔據了相當大份額；第二階段從 1995 年到 2000 年，這一階段由於標準模板庫和後來的 Boost 等程式庫的出現，泛型程式設計在 C++ 中佔據了越來越多的比重。當然，同時由於 Java、C# 等語言的出現和硬體價格的大規模下降，C++ 受到了一定的衝擊；第三階段從 2000 年至今，由於以 Loki、MPL (Boost) 等程式庫為代表的產生式程式設計和模板元程式設計的出現，C++ 出現了發展歷史上又一個新的高峰，這些新技術的出現以及和原有技術的融合，使 C++ 已經成為當今主流程式設計語言中最複雜的一員。

比雅尼・史特勞斯特魯普工作起於 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 語言中的增值運算子）。加入了新的特性，其中包括虛擬函式、函式名和運算子多載、參考、常數、使用者可控制的自由空間儲存區控制、改良的型別檢查，並恢復了 BCPL 風格的雙斜線（`//`）單行注釋（之後 C99 也支援了這種注釋）。

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++ 標準是 2020 年 12 月發布的 _ISO/IEC 14882:2020_，又稱 C++20。

雖然 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++，這通常被一些權威著作認為是不正確的）。

### C++ 標準

由 ISO/IEC JTC1/SC22/WG21 進行。已經出版的標準文件如下：

## 設計原則

在《C++ 語言的設計和演化》（1994）中，Bjarne Stroustrup 描述了他在設計 C++ 時，所使用的一些原則。知道這些原則有助於理解 C++ 為何會是現在這個樣子。以下總結了一些原則，詳盡的內容可參閱《C++ 語言的設計和演化》：

* C++ 設計成直接的和廣泛的支援多種程式設計風格（過程化程式設計、資料抽象化、物件導向程式設計、泛型程式設計）。
* C++ 設計成給程式設計者更多的選擇，即使可能導致程式設計者選擇錯誤。
* C++ 設計成儘可能與 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++ 在某些案例中（見下「與 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++ 不是第一個正式引入 `const` 型別的語言。80 年代早期，Bjarne Stroustrup 和 Dennis Retchie 討論之後提供了在 C 語言中 `readonly`/`writeonly` 的實現機制，並在帶類的 C 中取得了一定經驗。關鍵字 `const` 正式引入 C 語言是在 ANSI C89。這早於第一個 C++ 國際標準近十年，但此時 `const` 已被 C++ 實現普遍採用。

以下是和 C 語言相容的用法：

但是，`const` 在 C++ 中有更強大的特性。它允許在編譯時確定作為真正的常數表達式。例如，

此前 C 語言並不支援這樣的用法，直到 C99 允許用變數作為陣列長度（需要注意的是 C99 中的 VLA 支援執行期確定陣列長度，但 C++ 從未支援）。此外，C++ 中，命名空間作用域的 const 物件的名稱隱含內部連結。這意味著直接在標頭檔里定義 const 物件被多個原始檔包含時，也不會重定義。

在 C++11 及之後的 C++ 標準中，推薦使用擁有更嚴格語意的 `constexpr` 限定符來表示一個可以出現在常數表達式中的變數。const 可區分為頂層 const (top-level const) 和底層 const (low-level const)。

實際上，在語意表達方面，`const` 更多表示為「唯讀」，`constexpr` 才表示一定能在翻譯時確定的常數，但實際求值仍可能在執行時進行（只有像作為聲明陣列大小這樣確定要求常數表達式的上下文中，才會因為需要確保翻譯時必須確定所需的值而進行翻譯時求值）。C++20 引入了更嚴格的 `consteval` 和 `constinit` 的語法，直接限定特定的求值必須在翻譯時完成。不過，和 `const` 不同，後三者修飾聲明但不是型別限定符，不參與型別聲明構成複合型別，不通過型別檢查實現所謂的 const 正確性（const correctness），也不影響利用這些特性的相關 API 的型別簽章。

一些參照 C 和 C++ 設計的語言中，也存在類似的差異。例如，C# 同時具有 `readonly` 和 `const` 關鍵字，前者接近原始的「唯讀」（即最先被討論的 readonly 機制和 C 語言中的 `const`），而後者更接近 C++ 的 `const`。

## 與 C 不相容之處

C++ 有時被認為是 C 的超集（superset），但這並不嚴謹。

各個版本的 ISO/IEC 14882 的附錄 C 中都指出了 C++ 和 ISO C 的一些不相容之處。

大部分的 C 代碼可以很輕易的在 C++ 中正確編譯，但仍有少數差異，導致某些有效的 C 代碼在 C++ 中失效，或者在 C++ 中有不同的行為。

最常見的差異之一是，C 允許從 `void*` 隱式轉換到其它的指標型別，但 C++ 不允許。下列是有效的 C 代碼：

但要使其在 C 和 C++ _兩者_皆能運作，就需要使用顯式轉換：

另一個常見的可移植問題是，C++ 定義了很多的新關鍵字，如 `new` 和 `class`，它們在 C 程式中，是可以作為識別字（例：變數名）的。

C99 去除了一些不相容之處，也新增了一些 C++ 的特性，如 `//` 注釋，以及在代碼中混合使用。不過 C99 也納入幾個和 C++ 衝突的新特性（如：可變長陣列、原生複數型別和複合逐字常數），而 C++11 已經加入了相容 C99 預處理器的特性。

由於 C++ 函式和 C 函式通常具有不同的名字修飾和呼叫約定，所有在 C++ 中呼叫的 C 函式，須放在 `extern "C" { /* C函数声明 */ }` 之內。

## C++ 的 Hello World 程式

下面這個程式顯示「Hello, world!」然後結束執行：

這裡也可以使用 using 指令以避免多次聲明 std::——

如果使用「\n」代替以上代碼裡的「endl」，輸出結果相等。

std::endl 不僅僅會在某個輸出流中插入換行字元，還將執行輸出流的 flush () 函式（即重新整理緩衝區），而 '\n' 則不會。

 
根據 ISO C++ 的規定，全域 main 函式必須返回 int。
以下兩種形式是合法的：

不過，在一些編譯器（例如 Visual C++）上，

也是合法的。但是這樣的寫法相容性較差。

## 語言特性

### 運算子

分為

### 預處理器

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

#### 預處理器指令和巨集

預處理指令的運作方式是根據使用者定義的規則，簡單的把記號字元序列置換成其它的記號字元序列。它們進行巨集置換、含入其它的檔案（由底層至高階的特性，例如包含模組／包／單元／元件）、條件式編譯和條件式含入。例如：

原始代碼中出現的 `PI`，都將會替換為 `3.1415926535897932384626433832795028841971693993751`。另一個普遍的例子是

它將標準庫標頭檔 `iostream` 中所有的宣告都納入呼叫者所在的程式塊。除了以上提到的常用指令以外，還有幾個額外的預處理器指令，可以用來控制編譯流程、條件式含入或排除代碼區塊等等。

　
: _參閱預處理器和 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：

但是仍然需要注意，嚴格來說，C++ 中物件的概念和 C 的對應概念接近，表示的是具有特定型別的儲存，而非物件導向意義上的「物件」：一個物件不一定是類型別的。此外，C++ 意義上的「實例」僅指模板實例化的結果，而並不指物件。作為對比，Java 的「物件」和「實例」的概念和這裡的使用一致。

#### 封裝

封裝（Encapsulation）是將資料和處理資料的程式（procedure）組合起來，僅對外公開介面（interface），達到資訊隱藏（information hiding）的功能。封裝的優點是能減少耦合（Coupling）。C++、Java、C# 等語言定義物件都是在語法中明確地使用類別（Class）來做到封裝。

C++ 的類別對其成員（包括資料成員、函式成員）分為三種封裝狀態：

* 公有（public）：類別的使用者可以存取、使用該類別的此種成員。
* 保護（protected）：該類別的衍生類別可以存取、使用該類別的此成員。外部程式碼不可以存取、使用這種成員。
* 私有（private）：只有類別自身的成員函式可以存取、使用該類別的此成員。

一般可以將 C++ 類的對外介面設定為公有成員；類內部使用的資料、函式設定為私有成員；供衍生自該類別的子類別使用的資料、函式設定為保護成員。

#### 繼承

繼承（Inheritance）是指衍生類別（subclass）繼承基礎類別（superclass），會自動取得超類別除私有特質外的全部特質，同一類別的所有實體都會自動有該類別的全部特質，做到程式碼再用（reuse）。C++ 只支援類別構成式繼承，雖然同一類別的所有實體都有該類別的全部特質，但是實體能夠共享的實體成員只限成員函式，類別的任何實體資料成員乃每個實體獨立一份，因此物件間並不能共享狀態，除非特質為參考型別的屬性，或使用指標來間接共享。C++ 支援的繼承關係為：

* 公有繼承（public inheritance）：最常用繼承關係，含義是「is-a」關係，代表了在完全使用公有繼承的物件類別之間的層次關係（hierarchy）。
* 受保護繼承（protected inheritance）：基礎類別的公有或保護內容可以被衍生類別，以及由此衍生的其他類別使用。但是基礎類別對外界使用者是不可見的。衍生類別的使用者不能存取基礎類別的成員、不能把衍生類別轉換（造型）為基礎類別的指標或參照。
* 私有繼承（private inheritance）：基礎類別的公有或保護內容僅可以被衍生類別存取。但基礎類別對衍生類別的子類別或衍生類別的使用者都是不可見的。衍生類別的子類別或衍生類別的使用者都不能存取基礎類別的內容、不能把衍生類別轉換為基礎類別的指標或參照。

C++ 支援多繼承（multiple inheritance，MI）。多繼承（multiple inheritance，MI）的優缺點一直廣為使用者所爭議，許多語言（如 Java）並不支援多重繼承，而改以單一繼承和介面繼承（interface inheritance），而另一些語言則採用用單一繼承和混入（mixin）。C++ 通過虛繼承（Virtual Inheritance）來解決多繼承帶來的一系列問題。

### 多型

除了封裝與繼承外，C++ 還提供了多型功能，物件導向的精神在於多型（Polymorphism），一般的多型，是指動態多型，係使用繼承和動態繫結（Dynamic Binding）實現，使用多型可建立起繼承體系（Inheritance hierarchy）。類（class）與繼承只是達成多型中的一種手段，所以稱物件導向而非類別導向。

多型又分成靜態多型（Static Polymorphism）與動態多型（Dynamic Polymorphism）。C++ 語言支援的動態多型必須結合繼承和動態繫結（Dynamic Binding）方式實現。靜態多型是指編譯時決定的多型，包括多載和以模板（template）實現多型的方法即參數化型態（Parameterized Types），是使用巨集（macro）的「程式碼膨脹法」達到多型效果。

型別轉換（type cast）也是一種非參數化（ad hoc）多型的概念，C++ 提供 dynamic\_cast, static\_cast 等運算子來實作強制型別轉換（Coercion）。

運算元重載（operator overloading）或函式重載（function overloading）也算是多型的概念。

## 分析和處理 C++ 原始代碼

C/Java/C# 都可以用某種 LR 剖析器（或其變形）分析文法，但 C++ 是個著名的例外：請看下面的代碼。

上面的 table1 顯然是一個字串的二維陣列，而 table2 則未必能通過編譯：如果嚴格遵循 LR 分析過程，串 >> 會被解釋為右移運算子而非兩個代表模板參數列結束的右尖括號，因此出現編譯錯誤，必須以 table1 的方式用空格區分。(在 C++11 發布之後，特別規定了當處理模板時，>> 被優先視為兩個 >，所以 table1 和 table2 均可通過編譯.)

## 爭議

「在這 12 年裡，C++ 使用者人數大約每七個月半增加一倍」是許多 C++ 相關檔案必引的一段話；然而，時至今日新語言層出不窮，使用者人數已不太可能以如此速度增長。分析機構 EvansData 定期對開發人員展開調查，其資料顯示，以 C++ 為工具的開發人員在整個開發界所佔的比例由 1998 年春天的 76% 下降至 2004 年秋的 46%。

一部分 Unix/C 程式設計師對 C++ 語言深惡痛絕，他們批評的理由如下：

1. STL 以非常醜陋的方式封裝了各種資料結構和演算法，寫出來的代碼難以理解、不美觀。
2. C++ 編譯器複雜和不可靠，不適合構建人命關天類型的程式。
3. Ian Joyner 認為物件導向技術徒增學習成本，不如程序導向的 C 語言簡單容易使用，尤其是在系統軟體的構建上。

概括說來 UNIX 程式設計師批評 C++ 主要是由於 UNIX 社群與 C++ 社群的文化差異。

Linux 之父林納斯・托瓦茲曾經多次炮轟 C++。圖靈獎得主尼克勞斯・維爾特也曾經批評 C++ 語言太複雜、語法語意模糊，是「拙劣工程學」的成果。

事實上，對於 C++ 語言的批評並不只來源於 Unix/Unix-Like 系統下的程式設計師。就像 C++ 語言本身是一個跨平台的語言一樣，對 C++ 的批評並不局限於 Unix/Unix-Like 系統使用者。

## 參閱

* 《C++ 程式語言》（_The C++ Programming Language_）
* 比較 Java 和 C++
* C++ 代管擴展
* C++/CLI
* Boost C++ Libraries
* Objective-C ，另一個以 C 語言添加物件導向設計的程式語言

## 參考文獻

## 延伸閱讀

* Josuttis, Nicolai M. The C++ Standard Library, A Tutorial and Reference Second. Addison-Wesley. 2012. ISBN 0-321-62321-5.
* Lippman, Stanley B.; Lajoie, Josée; Moo, Barbara E. C++ Primer Fifth. Addison-Wesley. 2011. ISBN 0-321-71411-3. 
  * [美] Stanley B. Lippman; [美] Josée Lajoie; [美] Barbara E. Moo. C++ Primer (中文版)(第 5 版). 由王剛；楊巨峰翻譯。電子工業出版社. 2013-09-01. ISBN 9787121155352 （中文（中國大陸））.
* Meyers, Scott. Effective C++ Third. Addison-Wesley. 2005. ISBN 0-321-33487-6.
* Meyers, Scott. Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley. 2001.
* Stroustrup, Bjarne. The C++ Programming Language Fourth ed. Addison-Wesley. 2013. ISBN 978-0-321-56384-2.  引文格式 1 維護：冗餘文字 (link)
* Stroustrup, Bjarne. The Design and Evolution of C++. Addison-Wesley. 1994. ISBN 0-201-54330-3.
* Stroustrup, Bjarne. Programming Principles and Practice Using C++ Second ed. Addison-Wesley. 2014. ISBN 978-0-321-99278-9.  引文格式 1 維護：冗餘文字 (link)
* Vandevoorde, David; Josuttis, Nicolai M. C++ Templates: The complete Guide. Addison-Wesley. 2003. ISBN 0-201-73484-2.

## 外部連結

* JTC1/SC22/WG21（頁面存檔備份，存於網際網路檔案館） - The C++ Standards Committee （英文）
* C 和 C++ 資源的最終列表（頁面存檔備份，存於網際網路檔案館）
* C++ 教學 （頁面存檔備份，存於網際網路檔案館）
* C/C++ 參考手冊（中文）