C++强大的背后
核心提示:在31年前(1979年),1名刚取得博士学位的研究员,为了开发1个软件项目发明了1门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,4年后改称为C++。
在31年前(1979年),1名刚取得博士学位的研究员,为了开发1个软件项目发明了1门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,4年后改称为C++。C++是1门通用编程语言,支持多种编程范式,包括进程式、面向对象(object-oriented programming, OP)、泛型(generic programming, GP),后来为泛型而设计的模版,被发现及证实是图灵完备的,因此使C++亦可支持模版元编程范式(template metaprogramming, TMP)。C++继续了C的特点,既为高级语言,又含低级语言功能,可同时作为系统和利用编程语言。
C++广泛利用在不同领域,使用者以数百万计。根据近10年的调查,C++的流行程度约稳定排行第3位(于C/Java以后)。 C++经历长时间的实践和演变,才成为本日的样貌。1998年,C++标准委员会排除万难,使C++成为ISO标准(俗称C++98),当中含非常强大的标准模版库(standard template library, STL)。以后委员会在2005年提交了有关标准库的第1个技术报告(简称TR1),并为下1个标准C++0x而努力。惋惜C++0x其实不能在200x年完成,各界希看新标准能于2011年内出台。
流行的C++编译器中,微软Visual C++ 2010已实现部份C++0x语法并加进TR1扩充库,而gcc对C++0x语法和库的支持比VC2010更多。
应否选择C++
哪些程序适合使用C++?
C++并非万能丹,我按经验举出1些C++的适用时机。
C++合适构造程序中需求较稳定的部份,需求变化较大的部份可使用脚本语言;
程序须尽可能发挥硬件的最高性能,且性能瓶颈在于CPU和内存;
程序须频繁地与操纵系统或硬件沟通;
程序必须使用C++框架/库,如大部份游戏引擎(如Unreal/Source)及中间件(如Havok/FMOD),固然有些C++库提供其他语言的绑定,但通常原生的API性能最好、最新;
项目中某个目标平台只提供C++编译器的支持。
按利用领域来讲,C++适用于开发服务器软件、桌面利用、游戏、实时系统、高性能计算、嵌进式系统等。
使用C++还是C?
C++和C的设计哲学其实不1样,二者取舍不同,所以不同的程序员和软件项目会有不同选择,难以1概而论。与C++相比,C具有编译速度快、轻易学习、显式描写程序细节、较少更新标准(后二者也可同时视为缺点)等优点。在语言层面上,C++包括尽大部份C语言的功能(例外之1,C++没有C99的变长数组VLA),且提供OOP和GP的特性。但实在用C也可实现OOP思想,亦可利用宏往实现某程度的GP,只不过C++的语法能较简洁、自动地实现OOP/GP。C++的RAII(resource acquisition is initialization,资源获得就是初始化)特性比较独特,C/C#/Java没有相应功能。回顾历史,Stroustrup开发的早期C++编译器Cpre/Cfront是把C++源代码翻译为C,再用C编译器编译的。由此可知,C++编写的程序,都能用等效的C程序代替,但C++在语言层面上提供了OOP/GP语法、更严格的类型检查系统、大量额外的语言特性(如异常、RTTI等),并且C++标准库也较丰富。有时候C++的语法可使程序更简洁,如运算符重载、隐式转换。但另1方面,C语言的API通常比C++简洁,能较轻易供其他语言程序调用。因此,1些C++库会提供C的API封装,同时也可供C程序调用。相反,有时候也会把C的API封装成C++情势,以支持RAII和其他C++库整合等。
为甚么C++性能可优于其他语言?
相对运行于虚拟机语言(如C#/Java),C/C++直接以静态情势把源程序编译为目标平台的机器码。1般而言,C/C++程序在编译及链接时可进行的优化最丰富,启动时的速度最快,运行时的额外内存开消最少。而C/C++相对动态语言(如Python/Lua)也减少了运行时的动态类型检测。另外,C/C++的运行行动是肯定的,且不会有额外行动(例如C#/Java必定会初始化变量),也不会有如垃圾搜集(GC)而酿成的不肯定性延迟,而且C/C++的数据结构在内存中的布局也是肯定的。有时C++的1些功能会使程序性能优于C,当中之内联和模版最为突出,这两项功能使C++标准库的sort()通常比C标准库的qsort()快多倍(C可用宏或人手编码往解决此题目)。另1方面,C/C++能直接映照机器码,之间没有另1层中间语言,因此可以做底层优化,例如使用内部(intrinsic)函数和嵌进汇编语言。但是,很多C++的性能优点并非免费午饭,代价包括较长的编译链接时间和较易出错,因此增加开发时间和本钱,这点稍后补充。
我进行了1个简单全局渲染性能测试(512x512像素,每像素10000个采样),C++ 1小时36分、Java 3小时18分、Python约18天、Ruby约351天。评测方式和其他语言的结果详见博文。
C++常见题目
C++源代码跨平台吗?
C++有不错的跨平台能力,但由于直接映照硬件,因性能优化的关系,跨平台能力不及Java及多数脚本语言。但是,实践跨平台的C++软件还是可行的,但须留意以下题目:
C++标准没有规定原始数据类型(如int)的大小,需要特定大小的类型时,可自订类型(如int32_t),同时对任何类型使用sizeof()而不假定其大小;
字节序(byte order)按CPU有所不同,特别要留意2进制输进输出、reinterpret_cast法;
原始数据和结构类型的地址对齐有差异;
编译器提供的1些编译器或平台专用扩充指令;
避免作利用2进制接口(application binary inte***ce, ABI)的假定,例如调用函数时参数的取值顺序在C/C++中没定义,在C++中也不可随便假定RTTI/虚表等实现方式。
总括而言,跨平台C++软件可在头文件中用宏检测编译器和平台,再用宏、typedef、自定平台相干实现等方法往实践跨平台,C++标准不会提供这类帮助。
C++程序轻易崩溃?
和很多语言相比,C/C++提供不安全的功能以最优化性能,有可能造成崩溃。但要留意,很多运行时毛病,如向空指针/援用解援用、数组越界、堆栈溢出等,其他语言也会报错或抛出异常,这些都是程序题目,而不是语言本身的题目。有些意见以为,出现这类运行时毛病,应当尽可能写进日志并立即崩溃,不该让程序继续运行,以免造成更大的影响(例如程序继续把内存中毛病的数据覆写文件)。若要容错,可按业务把程序分割为多进程,像Chrome或使用fork()的情势。但是,C++有很多机制可以减少毛病,例如以string代替C字符串;以vector或array(TR1)代替原始数组(有些实现可在调试模式检测越界);使用智能指针也能减少1些原始指针的题目。另外,我最常碰到的Bug,就是没有初始化成员变量,有时会导致崩溃,而且调试版和发行版的行动可能不同。
C++要手动做内存治理?
C++同时提供在堆栈上的自动局部变量,和从自由存储(free store)分配的对象。对后者,程序员需手动开释,或使用不同的容器和智能指针。 C++程序员常常进1步优化内存,自定义内存分配策略以提升效能,例如使用对象池、自定义的单向/双向堆栈区等。固然C++0x还没加进GC功能,但也能够自行编写或使用现成库。另外,C/C++也能够直接使用操纵系统提供的内存相干功能,例如内存映照文件、共享内存等。
1 2 下1页
核心提示:在31年前(1979年),1名刚取得博士学位的研究员,为了开发1个软件项目发明了1门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,4年后改称为C++。
使用C++常要重造轮子?
我曾参与的C++项目,都会重造很多标准库已提供的功能,此情况在其他语言中较少出现。我试图分析个中缘由。首先,C++标准库相对很多语言来讲是贫乏的,各开发者便会重复地制造自订库。从另1个角度看,C++标准库是用C++编写的(很多其他语言不用本身而是用C/C++往编写库),在能力和性能上,自订库和标准库并没有本质差别;另外,标准库为通用而设,对不同平台及多种使用需求作取舍,性能上有所影响,例如EA公司就曾发表自制的EASTL规格,描写游戏开发方面对STL的性能及功能需求的特点;另外,多个C++库1起使用,常常会因规范不同而引发冲突,又或功能堆叠,所以项目可能须自行开发,或引进其他库的概念或实现(如Boost/TR1/Loki),改写以符合项目规范。
C++编译速度很慢?
错,是非常慢。我以为C++多是实用程序语言中编译速度最慢的。此题目触及C++沿用C的编译链接方式,又加进了复杂的类/泛型声明和内联机制,使编译时间倍增。在C++对编译方法改革之前(如module提案),可使用以下技能改良:第1,使用pimpl手法,因性能消耗利用于调用次数未几的类;第2,仅包括必要头文件,并尽可能使用及提供前置声明版本的头文件(如iosfwd);第3采取基于接口的设计,但须留意虚函数调用本钱;第4,采取unity build,即把多个cpp文件结合在1个编译单元进行编译;第5,采取散布式天生系统如IncrediBuild。
C++缺少甚么功能?
固然C++已非常复杂,但仍缺少很多常见功能。 C++0x作出了很多改良,例如语言方面加进Lambda函数、闭包、类型推导声明等,而库方面则加进正则表达式、采取哈希表的unordered_set/unordered_map、援用计数智能指针shared_ptr/weak_ptr等。但最值得留意的是C++0x引进多线程的语法和库功能,这是C++演进的1大步。但是,模组、GC、反射机制等功能虽有提案,却未加进C++0x。
C++使用建议
为利用挑选特性集
我同意Stroustrup关于使用C++各种技术的回应:“你可以做,不意味着你必须这么做。(Just because you can do it, doesn‘t mean that you have to.)” C++布满丰富的特性,但同时带来不同题目,例如过分复杂、编译及运行性能的消耗。1般可考虑是否是使用多重继续、异常、RTTI,并调理使用模版及模版元编程的程度。使用过分复杂的设计和功能,可能会令部份团队成员更难理解和保护。
为团队建立编程规范
C++的编码自由度很高,轻易编写风格差异的代码,C++本身也没有定义1些标准规范。而且,C++的源文件物理构成,较很多语言复杂。因此,除决定特性集,每个团队应建立1套编程规范,包括源文件格式(可使用文件模版)、花括号风格。
尽可能使用C++风格而非C风格
由于C++有对C兼容的包袱,1些功能可使用C风格实现,但最好使用C++提供的新功能。最基本的是尽可能以具名常量、内联函数和泛型取代宏,只把宏用在条件式编译及特殊情况。旧式的C要求局部变量声明在作用域开端,C++则无此限制,应把变量声明尽可能置于邻近其使用的地方,for()的循环变量声明可置于for的括号内。 C++中能加强类型安全的功能应尽可能使用,例如避免“万能”指针void *,而使用个别或泛型类型;用bool而非int表示布尔值;选用4种C++ cast关键字代替简单的强迫转换。
结合其他语言
如前文所述,C++并非合适所有益用情境,有时可以混合其他语言使用,包括用C++扩大其他语言,或在C++程序中嵌进脚本语言引擎。对后者,除使用各种脚本语言的专门API,还可使用Boost或SWIG作整合。
C++学习建议
C++缺点之1,是相对很多语言复杂,而且难学难精。很多人说学习C语言只需1本K&R《C程序设计语言》即可,但C++书籍却是多不胜数。我是从C进进C++,皆是靠浏览自学。在此分享1点学习心得。个人以为,学习C++可分为4个层次:
第1层次,C++基础:挑选1本进门书籍,如《C++ Primer》、《C++大学教程》、或Stroustrup撰写的经典《C++程序设计语言》或他1年半前的新作《C++程序设计原理与实践》,而1般C++课程也止于此,另外《C++ 标准程序库》及《The C++ Standard Library Extensions》可供参考;
第2层次,正确高效地使用C++:此层次开始必须自修,浏览过《(More)Effective C++》、《(More)Exceptional C++》、《Effective STL》及《C++编程规范》等,才适合踏进专业C++开发之路;
第3层次,深进了解C++:关于全局题目可读《深进探索C++对象模型》、《Imperfect C++》、《C++寻思录》、《STL源码剖析》,要挑战智商,可看关于模版及模版元编程的书籍如《C++ Templates》、《C++设计新思惟》、《C++模版元编程》;
第4层次,研究C++:浏览《C++语言的设计和演变》、《编程的本质》(含STL设计背后的数学根基)、C++标准文件《ISO/IEC 14882:2003》、C++标准委员会的提案书和报告书、关于C++的学术文献。
由于我主要是利用C++,大约只停留于第2、3个层次。但是,C++只是软件开发的1环而已,单凭语言其实不能应付业务和工程上的题目。建议读者不要强求几年内“完全学会C++的知识”,到达第2层左右便从工作实战中汲取经验,有爱好才渐渐继续学习更高层次的知识。固然学习C++有难度,但也是相当有趣且有满足感的。
数10年来,C++虽有起伏,但她依托其使用者而不断得到顽强的生命力,相信在我退休之前都不会与她分离,也希看更进1步了解她,与她走进未来。
本文转自博客园 原文:C++强大背后
上1页 1 2 http://www.fw8.net/TAG:程序,功能,性能,语言,标准
评论加载中...
|