C++

C++是一种使用广泛的计算机程序设计语言。它是一种通用程序设计语言，支援多重编程模式，例如程序化程序设计、数据抽象、面向对象程序设计、泛型程序设计和设计模式等。

比雅尼·斯特劳斯特鲁普博士在贝尔实验室工作期间在20世纪80年代发明并实现了C++。起初，这种语言被称作“”（“包含‘类’的C语言”），作为C语言的增强版出现。随后，C++不断增加新特性。虚函数（）、运算符重载（）、多继承（）、标准模板库（, ）、异常处理（）、运行时类型信息（）、命名空间（）等概念逐渐纳入标准。1998年，国际标准组织（）颁布了C++程序设计语言的第一个国际标准ISO/IEC 14882:1998，目前最新标准为ISO/IEC 14882:2017。根据《C++编-{}-程思想》（）一书，C++与C的代码执行效率往往相差在±5%之间。

C++语言发展大概可以分为三个阶段：第一阶段从80年代到1995年。这一阶段C++语言基本上是传统类型上的面向对象语言，并且凭借着接近C语言的效率，在工业界使用的开发语言中占据了相当大份额；第二阶段从1995年到2000年，这一阶段由于标准模板库（）和后来的Boost等程式库的出现，泛型程序设计在C++中占据了越来越多的比重。当然，同时由于Java、C#等语言的出现和硬体价格的大规模下降，C++受到了一定的冲击；第三阶段从2000年至今，由于以Loki、MPL(Boost)等程式库为代表的产生式编程和模板元编程的出现，C++出现了发展历史上又一个新的高峰，这些新技术的出现以及和原有技术的融合，使C++已经成为当今主流程序设计语言中最复杂的一员。

比雅尼·史特劳斯特鲁普（）工作起于1979年的。这个构思起源于斯特劳斯特鲁普做博士论文时的一些程式撰写经验。他发现Simula具备很利于大型软体开发的特点，但的执行速度太慢，无法对现实需求发挥功效；BCPL虽快得多，但它过于低阶的特性，使其不适于大型软体的开发。当斯特劳斯特鲁普开始在贝尔实验室工作时，他有分析UNIX核心关于分散式计算的问题。回想起他的博士论文经验，斯特劳斯特鲁普开始为C语言增强一些类似的特点。之所以选择C，是因为它适于各种用途、快速和可移植性。除了C和Simula之外，同时也从其它语言中取得灵感，如ALGOL 68、Ada、CLU以及ML。

刚开始时，类别、衍生类别、储存类型检查、内联和缺省参数特性，都是透过Cfront引入C语言之中。

1983年，改命名为C++（codice_1是C语言中的增值操作符）。加入了新的特性，其中包括虚拟函式、函式名和运算子多载、参考、常数、使用者可控制的自由空间储存区控制、改良的型别检查，以及新的双斜线（codice_2）单行注解风格。

1985年，发布第一版《C++程式设计语言》，提供一个重点的语言参考，至此还不是官方标准。1985年10月出现了第一个商业化发布。

1989年，发布了。引入了多重继承、抽象类别、静态成员函式、常数成员函式，以及成员保护。1990年，出版了"The Annotated C++ Reference Manual"。这本书后来成为标准化的基础。稍后还引入了模板、例外处理、命名空间、新的强制类型转换，以及布林类型。

随著C++语言的演变，也逐渐演化出相应的标准程式库。最先加进C++标准函式库的是串流程式库，其用以取代传统的C函式，如printf和scanf。随后所引入的程式库中最重要的便是标准模板库，简称STL。

多年后，一个联合的ANSI-ISO委员会于1998年对C++标准化（"ISO/IEC 14882：1998"）。在官方释出1998标准的若干年后，委员会处理缺陷报告，并于2003年发布一个C++标准的修正版本。2005年，一份名为Library Technical Report 1（简称）的技术报告释出。虽然还不是官方标准的一部分，不过它所提供的几个扩展可望成为下一版C++标准的一部分。几乎所有目前仍在维护的C++编译器皆已支援。

目前最新的C++标准是2017年12月发布的"ISO/IEC 14882:2017"，又称C++17或C++1z。

虽然C++免专利，但标准文件本身并不是免费的，尽管标准文档不是免费的，但是很容易从网络中取得，最简单的就是C++标准文档之前的最后一次草稿版本，它与标准的差别几乎只在于排版上。

C++这个名字是Rick Mascitti于1983年中所建议的，并于1983年12月首次使用。更早以前，尚在研究阶段的发展中语言曾被称为「」，之后是「」。在电脑科学中，C++仍被称为C语言的上层结构。它最后得名于C语言中的「++」运算子（其对变数的值进行递增）。而且在共同的命名约定中，使用「+」以表示增强的程式。斯特劳斯特鲁普说：「这个名字象征著源自于C语言变化的自然演进」。C+是一个和C/C++无关的早期程式语言。

Rick Mascitti在1992年被非正式地问起名字的由来，他表示这是在半开玩笑中说出的。他从没想过C++会成为这门语言的正式名字。

有一个关于C++名字的笑话是，当你使用后缀++时，附加只发生在运算之后（因此，它应该是++C，而不是C++，这个笑话是说时下某些程序员还在以使用C的方式使用C++，这通常被一些权威著作认为是不正确的）。

由进行。已经出版的标准文档如下：
在《C++语言的设计和演化》（1994）中，描述了他在设计C++时，所使用的一些原则。知道这些原则有助于理解C++为何会是现在这个样子。以下总结了一些原则，详尽的内容可参阅《C++语言的设计和演化》：


1998的C++标准分为两个部分：核心语言和C++标准程式库；后者包含了大部分标准模板库和C标准程式库的稍加修改版本。存在许多不属于标准部分的C++程式库，且使用外部连结，程式库甚至可以用C撰写。

C++标准程式库充分吸收了C标准程式库，并佐以少许的修改，使其与C++良好的运作。另一个大型的程式库部分，是以标准模板库（）为基础，于1994年2月正式成为ANSI/ISO C++。它提供了实用的工具，如容器类（如：Array和），迭代器（广义指针）提供容器以类似阵列的存取方式，以及泛型算法进行搜寻和排序的运算。此外还提供了(multi)map和(multi)set，它们都共享相似的成员函数。因此，以下成为可能，使用模板撰写泛型算法，它可以和任何容器或在任何以迭代器定义的序列上运作。如同C，使用codice_3指令包含标准表头，即可存取程式库里的功能。C++提供69个标准表头，其中19个不再赞成使用。

使用标准模板库（例如：使用codice_4或codice_5来取代C风格的数组或字符数组）有助于导向更安全和更灵活的软件。

在STL在纳入C++标准以前，是来自HP和后来的SGI的第三方程式库，标准中并未称之为「」，它只是标准库中的一部分，但仍有许多人使用这个名称，以别于其它的标准库（输入／输出串流、国际化、诊断、C程式库子集，等等）。
另外，如codice_6此类标准委员会添加的接口，有时也被误认为；实际上它们并不存在于原始的中，在标准化后才从标准库吸收加入其中。

和C语言相比，C++引入了更多的特性，包括：复合类型（引用类型等）、限定符和常量表达式、类型处理运算符（类型别名及和等多种类型指示符）、C++标准库（库与多种容器类）与迭代器、动态内存与智能指针、函数重载、面向对象程序设计（如数据抽象、成员函数、类作用域、构造函数与析构函数、静态成员、访问控制与继承、虚函数、抽象类与接口等）、拷贝控制、运算符重载、造型与函数风格的强制类型转换、模板与泛型编程，以及异常处理、命名空间、多继承与虚继承、运行时类型识别及嵌套类等。

和普遍认为的相反，C++不是第一个正式引入codice_7关键字的语言。80年代早期，和讨论之后提供了在C语言中的实现机制，并在带类别的C中取得了一定经验。关键字codice_7正式引入C语言是在。这早于第一个C++国际标准近十年，但此时codice_7已被C++实现普遍采用。

C++在某些案例中（见下「与C不相容之处」），进行比C还要多的类型检查。

以「codice_2」起始作为注解起源自C的前身BCPL，而后被重新引入到C++。

C++的一些特性，C不久之后也采用了，包括在循环的括号中声明，C++风格的注解（使用codice_2符号，和codice_12，虽然C99定义的codice_12关键字与C++的定义不相容。不过，C99也引入了不存在于C++的特性，如：可变参数巨集，和以阵列作为参数的较佳处理；某些C++编译器可能实作若干特性，以作为扩展，但其余部分并不符合现存的C++特性）

一个常见的混淆其实只是一个微妙的术语问题：由于它的演化来自C，在C++中的术语物件和C语言一样是意味著记忆体区域，而不是-{zh:类别;zh-tw:类别;zh-cn:类}-的实体，在其它绝大多数的物件导向语言也是如此。举例来说，在C和C++中，语句codice_14定义一个codice_15型别的物件，这就是变数的值codice_16将在指派时，所存入的记忆体区域。

codice_7是一个C和C++语言的关键字，意思是宣告一个常数(不能改变的变数)，即唯读。使用codice_7在一定程度上可以提高程序的安全性和可靠性，也便于实现对此进行优化（如把只读对象放入ROM中）。codice_7作为-{zh:型别;zh-tw:型别;zh-cn:类型}-限定符，是型别的一部分。

以下是和C语言相容的用法：
但是，codice_7在C++中有更强大的特性。它允许在编译时确定作为真正的常量表达式。例如，

此前C语言并不支持这样的用法，直到C99允许用变量作为数组长度（需要注意的是C99中的支持运行期确定数组长度，但C++从未支持）。此外，C++中，命名空间作用域的对象的名称隐含内部链接。这意味着直接在头文件里定义对象被多个源文件包含时，也不会重定义。

在C++11及之后的C++标准中，推荐使用拥有更严格语义的codice_21限定符来表示一个可以出现在常量表达式中的变量。

实际上，在语义表达方面，const更多表示为“只读”，constexpr才表示编译期常量。

C++有时被认为是C的超集（），但这并不严谨。

各个版本的的附录C中都指出了C++和的一些不兼容之处。

大部分的C代码可以很轻易的在C++中正确编译，但仍有少数差异，导致某些有效的C代码在C++中失效，或者在C++中有不同的行为。

最常见的差异之一是，C允许从codice_22隐式转换到其它的指标类型，但C++不允许。下列是有效的C代码：

但要使其在C和C++"两者"皆能运作，就需要使用显式转换：

另一个常见的可移植问题是，C++定义了很多的新关键字，如codice_23和codice_24，它们在C程式中，是可以作为识别字（例：变量名）的。

C99去除了一些不兼容之处，也新增了一些C++的特性，如codice_2注释，以及在代码中混合使用。不过C99也纳入几个和C++冲突的新特性（如：可变长数组、原生复数类型和复合逐字常数），而C++11已经加入了兼容C99预处理器的特性。

由于C++函数和C函数通常具有不同的名字修饰和调用约定，所有在C++中呼叫的C函数，须放在codice_26之内。

下面这个程序显示“Hello, world!”然后结束运行：
这里也可以使用指令以避免再次声明std::——
你可以用“\n”代替以上代码里的“”，不过必须用在句子的后端。请不要把斜杠（/）和反斜杠（\）混淆。

但需要知道的是， std::endl 不仅仅会在某个输出流中插入换行字符，还将执行输出流的 flush() 函数（即刷新缓冲区），而'\n'则不会。
根据ISO C++的规定，全局函数必须返回。
以下形式是合法的：

不过，在一些编译器（例如Visual C++）上，

也是合法的。不要这样写，因为这样的写法没有兼容性。

分为
C++主要有三个编译阶段：预处理、转译成目的码和连结（最后的两个阶段一般才视为真正的「编译」）。在第一阶段，预处理，会将"预处理器指令"替换成原始码，然后送到下一个编译阶段。

预处理指令的运作方式是根据使用者定义的规则，简单的把记号字元序列置换成其它的记号字元序列。它们进行巨集置换、含入其它的档案（由底层至高阶的特性，例如包含模组／包／单元／元件）、条件式编译和条件式含入。例如：

原始代码中出现的codice_27，都将会替换为codice_28。另一个普遍的例子是

它将标准库头文件codice_29中所有的声明语句都纳入调用者所在的程序块。除了以上提到的常用指令以外，还有几个额外的预处理器指令，可以用来控制编译流程、条件式含入或排除代码区块等等。

模板（）指C++程式语言中的函式模板（）与类别模板（），这种观念是取材自Simula的泛型程式设计。它采用typename和class两个关键字，来标识模板类别的型别参数。C++11和C++14分别引入了类型别名模板和变量模板。

在物件导向物件程式设计术语中，物件（）是资料（）和处理资料的指令（）的联合（）。模拟（）实际世界（），物件有三种特质（）：状态（）、行为（）、，并且使用讯息（）来引发彼此的互动。类别（）为物件的蓝图或工厂，定义了物件的抽象特质，包括物件的属性特质和物件的行为特质，属性的值即是物件的状态，行为即是物件能够做的事。

C++为类别构成式物件导向程式设计语言（），类别概念具现化（）地作为二等公民（）出现在C++语言当中，在语法中明确地使用类别来做到资料抽象化、封装、模组化、继承、子型别多型、物件状态的自动初始化。C++中，一个类别即为一个型别，加上封装，一个类别即为一个抽象资料型别（，），继承、多型、模板都加强了类别的可抽象性。在C++可以使用或这两个关键字宣告类别（），而使用运算子实体化类别产生的实体（）即为物件，是一等公民。C/C++以资料成员（）表达属性，以成员函式（）表达行为。

声明一个：

但是仍然需要注意，严格来说，C++中对象的概念和C的对应概念接近，表示的是具有特定类型的存储，而非面向对象意义上的“对象”：一个对象不一定是类类型的。此外，C++意义上的“实例”仅指模板实例化的结果，而并不指对象。作为对比，Java的“对象”和“实例”的概念和这里的使用一致。

封装（）是将资料和处理资料的程序（）组合起来，仅对外公开接口（），达到信息隐藏（）的功能。封装的优点是能减少耦合（）。C++、、C# 等语言定义对象都是在语法中明确地使用类别（）来做到封装。

C++的类别对其成员（包括数据成员、函数成员）分为三种封装状态：

一般可以将C++类的对外接口设定为公有成员；类内部使用的数据、函数设定为私有成员；供派生自该类别的子类别使用的数据、函数设定为保护成员。

继承（）是指派生类（）继承基类（），会自动取得超类别除私有特质外的全部特质，同一类别的所有实体都会自动有该类别的全部特质，做到程式码再用（）。C++只支援类别构成式继承，虽然同一类别的所有实体都有该类别的全部特质，但是实体能够共享的实体成员只限成员函式，类别的任何实体资料成员乃每个实体独立一份，因此物件间并不能共享状态，除非特质为参考型别的属性，或使用指标来间接共享。C++支持的继承关系为：

C++支持多继承（，）。多继承（，）的优缺点一直广为使用者所争议，许多语言（如Java）并不支援多重继承，而改以单一继承和介面继承（），而另一些语言则采用用单一继承和混入（）。C++通过虚继承（）来解决多继承带来的一系列问题。

除了封装与继承外，C++还提供了多型功能，物件导向的精神在于多态（），一般的多态，是指动态多态，系使用继承和动态绑定（）实现，使用多型可建立起继承体系（）。类（）与继承只是达成多态中的一种手段，所以称物件导向而非类别导向。

多态又分成静态多态（）与动态多态（）。C++语言支持的动态多态必须结合继承和动态绑定（）方式实现。静态多态是指编译时决定的多态，包括重载和以模板（）实现多型的方法即参数化型态（），是使用巨集（）的“程序代码膨胀法”达到多型效果。

类型转换（）也是一种非参数化（）多态的概念，C++提供dynamic_cast, static_cast等运算符来实作强制类型转换（）。

运算元重载（）或函式重载（）也算是多型的概念。

，但C++是个著名的例外：请看下面的代码。

上面的显然是一个字符串的二维数组，而则未必能通过编译：如果严格遵循分析过程，串 » 会被解释为右移运算符而非两个代表模板参数表结束的右尖括号，因此出现编译错误，必须以的方式用空格区分。(在C++11发布之后，特别规定了当处理模板时，»被优先视为两个>，所以table1和table2均可通过编译.)

「在这12年里，C++使用者人数大约每七个月半增加一倍」是许多C++相关文件必引的一段话；然而，时至今日新语言层出不穷，使用者人数已不太可能以如此速度增长。分析机构定期对开发人员展开调查，其资料显示，以C++为工具的开发人员在整个开发界所占的比例由1998年春天的76%下降至2004年秋的46%。

一部分程序员对C++语言深恶痛绝，他们批评的理由如下：


概括说来UNIX程式设计师批评C++主要是由于社群与C++社群的文化差异。

一个值得注意的事情是Linux之父Linus Torvalds曾经炮轰C++；图灵奖得主尼克劳斯·维尔特也曾经批评C++语言太复杂、语法语义模糊，是“拙劣工程学”的成果。

事实上，对于C++语言的批评并不只来源于系统下的程序员。就像C++语言本身是一个跨平台的语言一样，对C++的批评并不局限于系统用户。

一个确定的观点是：C++是一门复杂的语言、这门语言拥有过多的特性从而难以彻底掌握；C++的某些库难以学习、掌握并应用于实际当中；很多程序员都认为C++是一个过度设计的程序语言。