zoukankan      html  css  js  c++  java
  • 论C++0x新标准:欢迎还是拒绝?

    今天在CSDN上看到一篇文章,发现C++0x(或者称C++11或者C++0B)确实有很多令人兴奋的新特性,
    搜索一番,看了Stroustrup的C++11FAQ,颇有感想,因此希望与大家共享一下。想必大家都有自己
    的看法,欢迎探讨。

    1. 新特性展示,您是喜欢还是反感?

    以下我想展示几个目前可用的一些新特性,给不想花时间详细了解的读者一个直观感受。
    我使用MINGW GCC 4.6.1,注意加--std=c++0x或者--std=gnu++0x

    在C++98中,我要循环一个vector<string>:

    1 for(vector<string>::const_iterator itr = aVec.begin(); itr != aVec.end(); ++itr){
    2   cout << *itr << endl;
    3 }

    而在新标准中,这样就行了:

    1 for(auto e : aVec){ cout << e << endl;}

    这里展示了两个特性,新的auto关键字和ranged for。auto在新标准中语义变了,成为了
    编译器自动推导类型的意思。而原来的auto关键字几乎没有什么作用,local stack变量就是
    默认的,几乎见不到auto的使用。新标准中,使用原来的语义要产生错误的!ranged for也
    很好理解,就是学了Java或C#等语言的for循环,很方便。甚至可以这样:

    1 for(auto i : {1, 2, 3, 4, 5}) {cout << i << endl;}

    所以新的代码应该见到很多auto了,这并不是动态变量,而是简化了繁冗的工作,让编译器
    去做低级重复的事情。下面显示三种比较现代的C++:

    1 map<string, vector<int> > *myMap = new map<string, vector<int> >; // 最旧风格
    2 shared_ptr<map<string, vector<int> > > myMap = new map<string, vector<int> >; // 旧风格
    4 auto myMap = make_shared<map<string, vector<int>>>(); // 新风格

    make_shared是一个库函数,在VC2010中也能用,是一个非常方便的代替new的函数,直接返回
    创建对象的shared_ptr。新标准推荐显式使用智能指针,彻底杜绝delete。例如表达唯一拥有关系
    就用unique_ptr,表达共享关系就用shared_ptr,表达弱引用就用weak_ptr,只有表达非拥有关系,
    只是为了track一个对象的,才使用*。而且也不用担心模板的右尖括号问题了。

    还有一个小改动是值得注意的,就是类成员的初始化。大家知道在Java或C#中,变量初始话可以直接
    在声明时进行,而在C++中就必须在初始列表中,但是新标准也进行了改进,于是看以下代码:

    1 class A
    2 {
    3 static const int a = 3; // Ok in 89
    4 static int a = 3; // Error: not const in 89
    5 const int a = 3; // Error: not static in 89
    6 int a = 3; // Error in 89 but Ok in 0x
    7 public:
    8 A():a(0){} // Ok in 89 but not necessary in 0x
    9 }

    C++0x还有一个大的改动及加上了语言级别的lambda函数。及可以在需要使用函数指针或函数对象(所谓functor)
    的地方使用如下语法声明一个匿名函数:

    1 [](int a, int b){return a>b;}

    这相当于把boost的lambda函数库集成到语言中了,这样有几个好处,首先就是没有外部依赖,
    第二可能会降低模版导致的代码体积增大或效率问题。总体上来说是个不错的功能,以后C++的
    界面库就可以用类似的方法写event handler了。

    除了语言方面的一些列改进,标准库更是增加了不少内容。最显著的是thread、regex等,都是
    对C++能力(跨平台的基础上)的大幅扩充。具体大家可以查资料,在这里只是简单一提。

    2. C++0x,一门新语言?

    或许您已经查阅了很多C++0x相关的文章,或者您只是看了我上面简短的介绍,您对
    C++的演化抱有什么态度呢?我在CSDN等地看到的更多是抱怨,很多菜鸟认为过于复杂,
    难于学习入门。C++他爸认为C++0x是一门新语言,在某种程度上,还真是。

    我对C++也是经验有限,个人感觉C++的发展喜忧参半。对于把C++当成C with classes
    的人来说(大多数上点年纪的C++库都是如此用C++的),完全用新语言写的代码,真的有种陌生
    之感。我曾看到过一些大量使用模版的代码,唯一的感觉就是不必要的复杂性,或者是语言
    本身的无能,只能通过各种tricks来实现一些本该语言就能实现的东西。

    C++的模式太广了,如果是底层代码,其实用C加上几个类,就可以搞得很好;如果是应用
    开发,C++严重缺少的一个特性就是垃圾收集,为了提高效率,减少内存错误,于是基于模版
    的智能指针开始出现,就是为了在一个不适合做应用层开发的语言上提高易用性,又想
    不损失效率,后果就是不必要的复杂性。比如类型操作,大的框架都有反射机制,C++一定
    程度上也有,就是要损失效率,所以才有各种操作类型的模版。C++的模版真是物尽其用,
    被开发到了一种无以复加的程度,结果呢,使用模版的程序,体积快速膨胀,错误信息基本
    不可读,极大增加了调试难度,同时语言的学习曲线变陡了。

    C++的新标准旨在提高语言的易用性,一系列变化,很大程度上就是语法层面的改进,
    其实本质的语义改变很少。另一个就是把boost中成熟的库能加的都加进去(或者整合到语言
    里面),于是现代版的C++就出炉了。所以本质上看,C++0x还不是一个新语言。

    3. 从新标准看C++语言定位

    C++基于C语言并与其兼容的情况,使得对应用开发来说,其代码过于底层,开发效率
    低。而现代流行的编译型语言,例如C#或Java,隐藏了C++一些底层特征,而吸收了
    其一些高层表达方式,加上强大的类库支持,使得他们的易用性大大提高。如果利用Qt或者
    wxWidgets,C++也可以相对容易地完成一些应用开发,但是最终的程序,并不一定
    有很大的效率或体积优势(有兴趣的读者可以比较一下CodeBlocks和SharpDevelop
    两个IDE的运行时内存和速度)。

    那么C++到底怎么定位呢?C++0x似乎在向着应用开发方面发展,因为其试图通过
    智能指针隐藏C++内存管理的麻烦,用模版和类来实现各种高级语义,从而能够直接
    把问题映射为语言结构。标准库也对Unicode、Threading、Atomic Operation、标准
    容器、正则表达式等提供了完善的支持,我想把boost的FileSystem加进来,再有人
    实现一个跨平台的std::ui,那么C++可真可以和Java或C#坐一起了(或者是自降身份?)

    作为一个偏向系统编程的语言,却把泛型和lambda等高级语义作未来的方向,感觉
    C++的定位还真是有点复杂(也有点混乱)。

    其实做底层开发,把C++当做一个better C完全值得提倡。做游戏,用到的特性也就是类
    的封装,简化C一些繁琐的操作,因为很多C++特性用起来是会降低效率的。做界面等
    应用开发,C++的很多特性,和大公司打造的庞大平台(.Net或Java)相比,不论是优化、
    语言特性、易用性,还是类库支持,都是比不上的。有时候我感觉用C++的一个优势是
    不用强迫用户安装支持平台,但是现在随着Window7普及,.Net平台都默认装在那里了,
    真没有理由放着这么大好的资源不用,而用C++去做吃力不讨好的事情。Python等动态
    语言,随着硬件的升级,其效率劣势也逐渐消失,Ubuntu推荐的开发工具竟然是Python+
    PyGTK,其开发速度和体验,也是很好的,因为就像.Net之于Windows,Python现在
    基本是所有现代Linux发行版默认安装的语言了。你可能找不到gcc,但你一定可以用
    Python。且Python作为一个语言,在各方面都是具有绝对优势的。

    这么看来,如果C++不对语言本身进行重大变革(变成一个新语言),又想通过各种方式
    来提供高级语义,只能治标不治本,始终不适合所谓的高层开发(相对于底层)。

    4. 欢迎还是拒绝?

    现在C++11已经是标准了,只不过大多数编译器还没有完全实现而已。我们当然没有选择的
    权利,但是C++还是向下兼容的,于是我们可以选择是否使用新功能。

    我还是很喜欢C++的,对于有些简化编程的改进,真是举双手赞成。我甚至以后会一直打开
    --std=c++0x的选项,用上所有能用的新特性。如果这就是C++,我就这样用C++,但是
    如果我写C,我只会用C的功能,并且编译成C模块,ABI兼容性也是很好的。感觉现在
    C++和C有点像双重人格,亟待分为两个(真正意义上不同的)语言,然后各自发展。

    另外,C++的标准io库还是谨慎为妙(尤其是用gcc),有时会出现莫名其妙的问题,
    还是用C的stdio比较保险。且个人认为printf格式更加易用。

    这些改进对于初学者可能不是好事,因为初学者直接学C++的话(就像C++老爸那样,
    直接把C++当新语言教),就会很费解,这些都是什么乱七八糟的东西。只有学过C,
    或者学过C++的C子集,然后才能理解,例如,为什么这么多莫名奇妙的指针。因为
    C++本质上还是C的系统模型。

    C++老手可能会觉得,这些东西没什么,只不过是把久以形成的编程习惯固定化了。我甚至
    希望,以后C++的指针都默认是智能指针吧,这样能省多少事啊,但是这就打破了对C的兼容性。

    所以还是那句话,如果C++的语言本质没有改变,减少痛苦的改进还是欢迎的,但是这对于
    语言本身的发展并没有太大的意义。如果C++能生成新的语言,有志发展成为不在虚拟机上的
    大而全的开发平台,就是另一回事了。

  • 相关阅读:
    Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query
    Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了
    Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述
    Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
    Elasticsearch date 类型详解
    python 历险记(五)— python 中的模块
    python 历险记(四)— python 中常用的 json 操作
    python 历险记(三)— python 的常用文件操作
    Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
    Elasticsearch Java Rest Client API 整理总结 (一)——Document API
  • 原文地址:https://www.cnblogs.com/leading/p/on_cpp0x_welcome_or_deny.html
Copyright © 2011-2022 走看看