工业语言评审:应运而生,应运而长的C++

当Stroustrup博士开始到贝尔实验室开始他的第一份工作时,他并不知道自己应该做什么。他跑去问头儿,对方客气地回答他说,既然把您请来了,您想干什么就自己看着办吧。于是Stroustrup花了将近一年的时候找到了自己研究方向,但是他苦于没有合适的工具开展他的工作,基于自己的背景,他首先搞出来一个叫做C with Class这么一个东西供自己使用,它综合了C的强类型和Simula的类机制,前者对正确编程非常重要,而后者为复杂的建模提供了可能。每个人都会在日常工作中创造自己顺手的工具为我所用,但是Stroustrup博士不同。他有着严格的数学训练背景,熟读哲学而有着强烈的实用主义倾向,这些都决定了C++后来的风格。他相信这个东西对别人也有用,也愿意倾注精力来完善它。感谢所有这些,我们现在可以评审C++,这个使用最广泛的工业语言之一。

 

C++以支持多种编程范式著称。然而从工业使用的角度来说,多并不意味着好,我们追求的是以最小的代价解决问题, 然而界定最小的代价无疑是强相关的。比性能,C较之不分伯仲而更加简单;比易用,Java/C++后发优势而更胜一筹。那么C++的位置在那里?

 

C++的发展过程显示C++一直向如下方向努力:

  • 强类型,更强类型(同类型的不断分化和细化)

强类型在编译型的语言中显示出先天的优势,它用严格的类型匹配来保证语义的正确无误,有用灵活的缺省转换或者自定义转换把相关的类型连接在一起。通过细分不同的类型,程序员可以更准确地表达恰当的语义。对比C,C++的类型强化例子有:

常量对象和非常量对象的严格区分。C++领域,尽可能使用const关键字已经成为常识,其背后的含义了解的人却不多。这个区别是如此的重要,我们不惜引入两个新的关键字字来支持其全部特性:mutable和const_cast。前者使得类似延迟求值之类的优化有了用武之地,后者用来克服跨语言调用面临的类型匹配问题(如与C库集成)。

引用和指针的分野。本质上,二者的内部机制和外部行为完全一致。但是由于指针天生具有的弱相关性(延迟初始化,解除引用),强相关性的引用只能是另外一个独立的类型。引用保证了所指向对象的有效

更加严格的类型转换控制

然而,C++中并不是所有的都是强类型的,比如const char*代表的可能是真正的只读型编译期常量,也可能是可写的约定型常量。如下代码中v1和v2的属性截然不同,尽管它们的指向的值和类型完全一致:

[code:C++]

const char* v1 = "hello world";

const char* v2 = std::string("hello world").c_str();

[/code]

强类型对精确地描述解决方案非常有用。如果必须作强制的类型转化才能确保编译器不报错误,必需重新检查实现模型。

 

  • 原生类型和自定义类型的统一

按照Stroustrup的说法,原生类型(包括整数类型,浮点数类型,指针类型等几大类)不应该有任何的区别于自定义类型的特殊属性。在传统的强类型语言中,这样的要求似乎并无必要,因为人们每天面对的就是直接的类型。随着C++对泛型的支持不断增强,这样的要求就显得愈加重要。然而,由于C++本质上不是动态类型的,原生类型和自定义类型在细节上仍然存在微妙的差异,对于稍微通用一些的泛型实现,我们仍然要学习各种技巧来优化对基本类型的支持。C++几乎支持所有的操作符,这为灵活的实现提供了基础,也为滥用提供了可能。

  • 泛型,更泛型

本质上,之所以存在不同的类型,是因为我们试图以更精确的方式描述模拟物质世界,比如C++中存在8种不同的整数类型。然而这些类型在行为上表现的却相当一致,这是泛型引入的基础,也是避免代码重复的必需。很快,泛型就展现出更多的作用,并且深刻影响了我们的编程实现。比如基本类型的加法不会有任何的异常抛出,而泛型实现中却不能对使用的类型有任何的假设。异常安全的实现成了任何泛型库的基本要求。相对其他的语言,C++对库作者的要求更高。 

  • 更易于使用

如果一个工具仅仅是专家友好,它就很难在工业界得到广泛的应用。因为丰富的支持特性集,C++素来因为复杂而被初学者诟病。这个问题很复杂,但是根本上来,这不是C++的错,而是我们的教学方法出了问题。我们被教学习C++语言,而不是被教学习使用C++语言解决问题,就如同我们被教学习一门外语,而不是学习这门外语去解决沟通问题。然而,据此认为C++易于学习也是太过乐观。一些基本的解决问题的思想在任何语言中都是一致的,这是学习任何编程语言都要过的一关。学习C++之所以困难的问题在于我们总是被太多的细节所纠缠,看不出解决问题的思路。C++的语言特性很多,有不少是专门为库作者准备的尖刀利器,钻研太深需要大量的时间和实践。如果你的时间是一个常量,你用在真正学习解决问题上的时间就很少了。这样下去,你的投资长期没有回报,你的热情和信心就会减弱。幸运的是,情况并不都是这样。C++教学状况在不断改观(本系列稍后会有一个尝试性的C++入门刚要)。更重要的是,C++正在不断扩充它的特性域而慢慢变得初学者友好。有两个发展趋势:

1. 使常常导致问题的隐含约定显式化

2. 通过提供经验证的,有广泛使用基础的,良好封装的库 

  • 谨慎而持续地扩展基本库

相对很多的“现代”语言,C++提供的库无论从深度和广度来讲都差的不少。缘于C++最求极致性能和信任程序员的基本哲学,C++在库的扩展上相当保守,更不要说语言核心。然而,C++鼓励社区 

 

  • 着眼于问题分解和解决最基本的问题

所有复杂的问题的解决都依赖于有效地分解大问题为小问题,直至最基本的问题。在分解问题方面,C++提供的特性有:

  1. 面向对象的支持(实体继承,虚拟继承,多继承,动态绑定等)
  2. 强引用和弱引用
  3. 使用名字空间隔离复杂度

在解决基本问题上,C++的突出特色有:

  1. 泛型支持(容器,迭代器以及算法)
  2. 异常安全的资源管理
  3. 丰富的基本类型
  4. 灵活的编译连接模型
  5. 对性能的极其关注

总体看来,C++提供的支持并不像预期的那么多。仍然,相比于C,这是多么大的进步啊。之所以这样说,是因为C语言,尽管很老,仍然占据着工业编程的很大份额,而C++是其唯一成功的扩展。C++可以兼容绝大部分的C程序,这使得从C向C++的迁移变得相对容易。C++可以直接与操作系统应用编程接口交互,也提供了高级的控制问题复杂度的方法。这二者的平衡使得它在系统编程领域有着极大的优势。

 

然而不幸的是,C++远未达到完美。加之其本身支持特性之间复杂的交互,滥用这些特性导致理解C++代码更为困哪。相对于炫耀技巧,我们这里强调的是简洁和优雅。长期维护是工业编程的主要特征。C++有助于你达成这些目标,因为它提供了必需的构造,但是C++不能保证你一定能达成这些目标。我们还需要借助工程学的,社会学的以及心理学的成果。从对问题复杂性的讨论,到对C++语言特性的一个极其简要的梳理,我们非常快速地浏览了工业编程的现状和实现的主要的工具之一。那么,工业强度的实现究竟来自哪里?

 

我们稍后的讨论将以C++为主要的描述工具。在此之前,我们先复习一下C++,从工程师的角度。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值