为防止广告,目前nocow只有登录用户能够创建新页面。如要创建页面请先登录/注册(新用户需要等待1个小时才能正常使用该功能)。
C++
C++是一种使用非常广泛的计算机程式设计语言。C++是一种静态资料类型检查的,支援多范型的通用程式设计语言。它支援程序化程式设计、资料抽象化、物件导向程式设计、泛型程式设计等多种程式设计风格。
贝尔实验室的比雅尼·斯特劳斯特鲁普博士在20世纪80年代发明并实现了C++(最初这种语言被称作「C with Classes」)。一开始C++是作为C语言的增强版出现的,从给C语言增加类别开始,不断的增加新特性。虚函数(virtual function)、运算符重载(operator overloading)、多重继承(multiple inheritance)、模板 (C++)(template)、异常(exception)、RTTI、命名空间(name space)逐渐纳入标准。1998年国际标准化组织(ISO)颁布了C++程式设计语言的国际标准ISO/IEC 14882-1998。遗憾的是,由于C++语言过于复杂,以及他经历了常年的变更,直到现在(2004年)只有少数几个编译器完全符合这个标准。
另外,就目前学习C++而言,可以认为它是一门独立的语言;它并不依赖C语言,我们可以完全不学C语言,而直接学习C++。根据《C++编程思想》(Thinking in C++)一书所评述的,C++与C的效率往往相差在正负5%之间。所以有人认为在大多数场合中,C++完全可以取代C语言。
C++语言发展大概可以分为三个阶段:第一阶段从80年代到1995年。这一阶段C++语言基本上是传统类型上的物件导向语言,并且凭借着接近C语言的效率,在工业界使用的开发语言中占据了相当大份额;第二阶段从1995年到2000年,这一阶段由于标准模板库(STL)和后来的Boost等程式库的出现,泛型程式设计在C++中占据了越来越多的比重性。当然,同时由於Java、C#等语言的出现和硬体价格的大规模下降,C++受到了一定的冲击;第三阶段从2000年至今,由於以Loki、MPL等程式库为代表的产生式编程和模板元编程的出现,C++出现了发展历史上又一个新的高峰,这些新技术的出现以及和原有技术的融合,使C++已经成为当今主流程式设计语言中最复杂的一员。
目录 |
[编辑] 发展历史
Stroustrup工作起于1979年的C with Classes。这个构思起源于 Stroustrup 做博士论文时的一些程式撰写经验。他发现Simula具备很利於大型软体开发的特点,但Simula的执行速度太慢,无法对现实需求发挥功效;BCPL虽快得多,但它过於低阶的特性,使其不适於大型软体的开发。当Stroustrup开始在贝尔实验室工作时,他有分析UNIX核心关於分散式计算的问题。回想起他的博士论文经验,Stroustrup开始为C语言增强一些类似Simula的特点。之所以选择C,是因为它适於各种用途、快速和可移植性。除了C和Simula之外,同时也从其它语言中取得灵感,如ALGOL 68、Ada、CLU以及ML。刚开始时,类别、衍生类别、储存类型检查、内联和预设参数特性,都是透过Cfront引入C语言之中。1985年10月出现了第一个商业化发布。
1983年,C with Classes改命名为C++。加入了新的特性,其中包括虚疑函式、函式名和运算子重载、参考、常数、使用者可控制的自由空间储存区控制、改良的类型检查,以及新的双斜线(//)单行注解风格。1985年,发布第一版《C++程式设计语言》,提供一个重点的语言参考,至此还不是官方标准。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++免专利,但标准文件本身并不是免费的。
[编辑] C++名字的由来
C++这个名字是Rick Mascitti於1983年中所建议的,并于1983年12月首次使用。更早以前,尚在研究阶段的发展中语言曾被称为「new C」,之後是「C with Classes」。在电脑科学中,C++仍被称为C语言的上层结构。它最後得名於C语言中的「++」运算子(其对变数的值进行递增)。而且在共同的命名约定中,使用「+」以表示增强的程式。Stroustrup说:「这个名字象徵着源自於C语言变化的自然演进」。C+是一个和C/C++无关的早期程式语言。
Stroustrup addressed the origin of the name in the preface of later editions of his book, The C++ Programming Language, adding that "C++" might be inferred from the appendix of George Orwell's Nineteen Eighty-Four. Of the three segments of the fictional language Newspeak, the "C vocabulary" is the one dedicated to technical terms and jargon. "Doubleplus" is the superlative modifier for Newspeak adjectives. Thus, "C++" might hold the meaning "most extremely technical or jargonous" in Newspeak.
Rick Mascitti在1992年被非正式地问起名字的由来,他表示这是在半开玩笑中说出的。他从没想过C++会成为这门语言的正式名字。
有一个关于C++名字的笑话是,当你使用后缀++时,附加只发生在运算之後(因此,它应该是++C,而不是C++)。
[编辑] 未来发展
C++ continues to evolve to meet future requirements. One group in particular, Boost.org, works to make the most of C++ in its current form and advises the C++ standards committee as to which features work well and which need improving. Current work indicates that C++ will capitalize on its multi-paradigm nature more and more. The work at Boost, for example, is greatly expanding C++'s functional and metaprogramming capabilities. A new version of the C++ standard is currently being worked on, entitled C++0x (denoting the fact it is expected to be released before 2010) which will include a number of new features.
[编辑] 设计原则
在《C++语言的设计和演化》(1994)中,Bjarne Stroustrup描述了他在设计C++时,所使用的一些原则。知道这些原则有助于理解C++为何会是现在这个样子。以下总结了一些原则,详尽的内容可参阅《C++语言的设计和演化》:
- C++设计成静态类型、和C同样高效且可移植的多用途程式设计语言。
- C++设计成直接的和广泛的支援多种程式设计风格(程序化程式设计、资料抽象化、物件导向程式设计、泛型程式设计)。
- C++设计成给程式设计者更多的选择,即使可能导致程式设计者选择错误。
- C++设计成尽可能与C相容,籍此提供一个从C到C++的平滑过渡。
- C++避免平台限定或没有普遍用途的特性。
- C++不使用会带来额外开销的特性。
- C++设计成无需复杂的程式设计环境。
Stanley B. Lippman describes various models in his in-depth book "Inside the C++ Object Model" (1996) for how compilers may convert C++ program statements into an in-memory layout. Compiler vendors are free to implement the standard in their own manner. Lippman worked on implementing and maintaining Cfront, the original C++ implementation at Bell Labs.
[编辑] 标准程式库
1998的C++标准分为两个部分︰核心语言和C++标准程式库;後者包含了大部分标准模板库和C标准程式库的稍加修改版本。存在许多不属於标准部分的C++程式库,且使用外部连结,程式库甚至可以用C撰写。
C++标准程式库充分吸收了C标准程式库,并佐以少许的修改,使其与C++良好的运作。另一个大型的程式库部分,是以标准模板库(STL)为基础。它提供了实用的工具,如容器(如︰向量和链表),迭代器(一般化指标)提供容器以类似阵列的存取方式,以及演算法进行搜寻和排序的运算。此外还提供了(multi)map(关联阵列)和(multi)set,它们都使用相容的界面。因此,以下成为可能,使用模板撰写泛型演算法,它可以和任何容器或在任何以迭代器定义的序列上运作。如同C,使用#include
指令包含标准表头,即可存取程式库里的功能。C++提供69个标准表头,其中19个不再赞成使用。
使用标准库(例如︰使用std::vector
或std::string
来取代C风格的阵列)有助於导向更安全和更灵活的软体。
STL在纳入C++标准以前,是来自HP和後来的SGI的第三方程式库,标准中并未称之为「STL」,它只是标准库中的一部分,但仍有许多人使用这个名称,以别於其它的标准库(输入/输出串流、国际化、诊断、C程式库子集,等等)。
Most C++ compilers provide an implementation of the C++ standard library, including the STL. Compiler-independent implementations of the STL, such as STLPort, also exist. Other projects also produce various custom implementations of the C++ standard library and the STL with various design goals.
[编辑] C++中的特色
和C语言相比,C++引入了更多的特性,包括︰陈述性宣告,类似函式的强制转型,new/delete运算子,布林类型,参考类型,预设参数,函式重载,命名空间,类别(包括所有和类别相关的特性,如继承、成员函式、虚拟函式、抽象类别和建构子),运算子重载,模板,::
运算子,异常处理和执行时期识别。
和普遍认为的相反,C++不是第一个引入const关键字的。Const是在正式引入C语言不久之後,才被C++采用。
C++在某些案例中(见下「与C不相容之处」),进行比C还要多的类型检查。
以「//
」起始作为注解起源自C的前身BCPL,而後被重新引入到C++。
C++的一些特性,C不久之後也采用了,包括在for回圈中宣告,C++风格的注解(使用//
符号,和inline
,虽然C99定义的inline
关键字与C++的定义不相容。不过,C99也引入了不存在於C++的特性,如︰variadic macros,和以阵列作为参数的较佳处理;某些C++编译器可能实作若干特性,以作为扩展,但其余部分并不符合现存的C++特性)
一个常见的混淆其实只是一个微妙的术语问题︰由於它的演化来自C,在C++中的术语物件和C语言一样是意味着记忆体区域,而不是类别实体,在其它绝大多数的物件导向语言也是如此。举例来说,在C和C++中,语句int i;
定义一个int
类型的物件,这就是变数的值i
将在赋值时,所存入的记忆体区域。
[编辑] 与C不相容之处
C++一般被认为是C的超集,但这并不严谨。大部分的C代码可以很轻易的在C++中正确编译,但仍有少数差异,导致某些有效的C代码在C++中失效,或者在C++中有不同的行为。
也许最常见的差异是,C允许从void*
隐式转换到其它的指标类型,但C++不允许。下列是有效的C代码︰
int *i = malloc(sizeof(int) * 5); /* 从 void* 隐式转换为 int* */
但要使其在C和C++两者皆能运作,就需要使用显示转换︰
int *i = (int *) malloc(sizeof(int) * 5);
另一个常见的可移植问题是,C++定义了很多的新关键字,如new
和class
,它们在C程式中,是可以作为识别字(例︰变数名)的。
在最新的C标准(C99)中去除了一些不相容之处,目前也支援了C++的特性,如//
注解,以及在代码中混合宣告。不过C99也纳入几个和C++冲突的新特性(如︰可变长度阵列、原生复数类型和复合逐字常数),所以语言的分岐可能还是大过合并。
若要混用C和C++的代码,则所有在C++中呼叫的C代码,必须放在extern "C" { /* C代码 */ }
之内。
[编辑] C++的Hello World程序
在使用兼容C89标准(也称为ANSI C)的编译器时,下面这个程序显示“Hello, world!”然后结束运行:
#include <iostream> int main() { std::cout << "Hello, world!\n"; }
在使用兼容C99标准(ISO/IEC 14882-1998)的编译器时,下面的程序也是可以的:
#include <iostream> using namespace std; int main() { cout << "Hello, world!" << endl; return 0; }
根据ISO C++的规定,main函数的形式只能是
int main() { ... }
以及
int main(int argc,char * argv[]) { ... }
尽管如此,但在大部份编译器上,
void main() { .... }
也被支持。
#include<iostream.h> void main() { cout<<"Hello, world!" << endl; }
[编辑] 语言特性
[编辑] 运算子
[编辑] 预处理器
C++主要有三个编译阶段︰预处理、转译成物件码和连结(最後的两个阶段一般才视之为真正的「编译」)。在第一阶段,预处理,会将预处理器指令替换成原始码,然後送到下一个编译阶段。
[编辑] 预处理器指令和巨集
预处理指令的运作方式是根据使用者定义的规则,简单的把记号字元序列置换成其它的记号字元序列。它们进行巨集置换、含入其它的档案(由底层至高阶的特性,例如包含模组/包/单元/元件)、条件式编译和条件式含入。例如:
#define PI 3.1415926535897932384626433832795028841971693993751
每次在原始码中出现的PI
,将会替换为3.1415926535897932384626433832795028841971693993751
。另一个普遍的例子是
#include <iostream>
它从标准库表头iostream
含入(汇入)所有的符号。除了以上提到的常用指令以外,还有几个额外的预处理器指令,可以用来控制编译流程,条件式含入或排除代码区块等等。
[编辑] 模板
[编辑] 物件
[编辑] 封装
[编辑] 继承
[编辑] 多态
[编辑] 分析和处理C++原始码
[编辑] 问题与争论
[编辑] 中文术语问题
[编辑] 使用者人数
Stroustrup最初在《C++语言的设计和演化》一书中所提及的使用者爆炸性增长的资料为︰
年份 | 估计使用者人数 |
1979 | 1 |
1980 | 16 |
1981 | 38 |
1982 | 85 |
1983 | ?? + 2 |
1984 | ?? + 50 |
1985 | 500 |
1986 | 2000 |
1987 | 4000 |
1988 | 15000 |
1989 | 50000 |
1990 | 150000 |
1991 | 400000 |
而作出「在这12年里,C++使用者人数大约每七个月半增加一倍」的结论,并成为许多C++相关文件必引的一段话。然而,时至今日新语言层出不穷,使用者人数已不太可能以如此速度增长。
分析机构EvansData定期对开发人员展开调查,其调查结果与Stroustrup提出的C++正在扩张的说法相违背。EvansData的资料显示,以C++为工具的开发人员在整个开发界所占的比例由1998年春天的76%下降至2004年秋的46%。
Forrester最新的调查显示,C++、微软VisualBasic和Java是众多公司产品体系的首选语言。对100家公司的调查显示,C/C++、VisualBasic和Java在产品体系中的使用比例分别是59%、61%和66%。