huaxiazhihuo

 

C++杂谈

       C++是我最喜欢的语言,它集自由、博大、复杂、简约、高效于一身,又能很好地均衡这些特点,使它们和平共处,将“不为用到的任何特性付出一点点代价”的宗旨贯彻到底,其他的任何一种语言的都不具备像C++这样的内涵,使用C++之时,直有C++在手,江山我有的感觉。C虽然能让你掌管一切,但用C开发,有如戴着镣铐在跳舞,无时不刻要小心翼翼地人肉管理一切细节,实在太累了。而用C#、JAVA等其他语言时,虽然养尊处优,但想走不寻常路之时,又处处受限制,很有点寄人篱下的味道,未免不痛快。只有C++,既能下,又能上,进可攻,退可守,想怎么样就怎么样,尽情地飞翔。只要你愿意,你就可以在这一片世界里随心所欲地发挥你的一切聪明才智,创造出种种奇技淫巧,而不会受到一点点约束。问题来了,自由得过头了,就失去了控制,自由未必是好事。好多人,自由得甚至忘记了他要用C++的根本目的是什么,于是,C++到了他的手里,就变成为自由而自由,为复杂而复杂的利器,不但用它来折磨自己,还用它来迷惑别人,以致于忽视了原本要解决的问题,这样一来,问题就很严重了。好的工具本来就是要用来做点实事的,做不了实事,要拿什么来证明自己呢?

        对于C++,没什么好说的。但C++的教育,就有太多的不满,要指责之处,也实在太多了,其中最为人诟病,就是很多C++的教材,都鼓励读者将注意力集中到C++的细节中,而忘记了如何用C++来简洁质朴地来表达设计思路。关于这一点,很多达人君子也已经一再严厉地批评再批评。我也不想重复他们的论调,只想举两个例子。

        C++因缺乏GC,而广受非议。但内存管理,其实不值得议论再议论,只要设计编写得当,少耍小聪明,代码中出现new和delete的次数可以很少很少,就算出现,也只会出现于底层代码中。为了弥补GC的缺席,C++界中发明了种种内存管理的巧妙手法,其中最得力的一种办法就是智能指针,而出现于标准库中就是大名鼎鼎的auto_ptr了,甚至有人说,一本C++的教材,只要不介绍auto_ptr,就不属于合格的教科书。但其实,auto_ptr并不见得那么重要,好比以下的代码
Int* pa = new int;
……
delete pa;
        这代码确实不好,于是该auto_ptr上场表演,变成
auto_ptr<int*> pa(new int);
        delete消失了,何其美妙,但其实,最朴实的代码,连new都可以不用的,既然没有new,就不需要auto_ptr了,最简洁的代码,非常简单。
Int a = 0;
        一行就好,什么都用不了,很多出现auto_ptr的地方,直接用局部变量就可以了。不能使用局部变量的地方,就属复杂的内存管理了,在那里分配,在那里释放,都很有必要细细地斟酌一番,auto_ptr并非什么万能丹,一有内存分配,就搬出auto_ptr,只怕属本本主义的作风。即此以观,什么share_ptr,scope_ptr,也就那么一点点作用而已,无须大书特书。

        我承认,BOOST精妙无比,那都是C++程序聪明才智的结晶,但其实,真正搬得上台面,发挥大作用的玩意,为数并不多,好比Tuple,可以方便地返回函数中的多个结果,例如……(请大家自己动手,或baidu或google),乍听起来,似乎美妙无比。但其实,没什么作用,什么时候,我们需要从函数中返回多个值?需要从函数中返回多值时,我会尽量地写本地代码,实在必须调用函数了,只好搬出指针或引用,将参数传递进去,如果数量太多了,那就动用结构,用结构组织这些返回值,这一切,做起来,并没什么太大的不便。但是如果动用Tuple返回多个结果,可能方便了那么一点点,却将导致代码难以维护,因为Tuple里面的值各表示了什么意思,无法直接从代码中看得出来,用过Tuple的同学自然知道我要说什么。Tuple的实现非常巧妙,如此费尽心思弄出来的东西,不过是一只漂亮花瓶而已,真让人扼腕叹息不已,很多C++的库,尤其是BOOST,都是这个样子,看起来很精致,用起来,却完全不是那么一回事,而且还引入很多不必要复杂性,世人称心智包袱。

        ……
        用C++做设计,很容易就导致库设计,如果设计出来的库有用好用,那也罢了,问题是费了九牛二虎之力,搞出来的东西,半点得不到别人的认可,甚至连自己都无法认可,那就太不应该了。
        用C++写代码,老老实实地写代码,不要忘记了编程的用意,别沉浸于语言中,尽量将代码写得直白易懂,少卖弄聪明才智, 慎用C++的一切特性,继承、虚函数、操作符重载、模板、异常、new delete、……,更加不要用它们创造出什么奇技淫巧,必须用它们的时候,必须要有使用它们的理由。确实存在必须使用它们的理由,还坚决不用,那就是傻瓜和偏执狂了,这不是合格的C++码农,C++虽然不喜欢胡作非为的捣蛋鬼,但也杜绝一切墨守成规的书呆子。

posted on 2011-07-11 09:29 华夏之火 阅读(2787) 评论(30)  编辑 收藏 引用

评论

# re: C++杂谈 2011-07-11 10:14 Enic

90%赞同,感同身受,,,  回复  更多评论   

# re: C++杂谈 2011-07-11 10:22 Skill

那是因为你不懂得使用Boost,标准委员会几千人的结晶就被你一句话否决了
好好学一学吧 你太依赖auto_ptr了  回复  更多评论   

# re: C++杂谈 2011-07-11 10:52 华夏之火

@Skill
只怕阁下更不懂得Boost和auto_ptr,而且也未必明白在下的文章要说什么,只想说在下最不依赖auto_ptr了
  回复  更多评论   

# re: C++杂谈 2011-07-11 11:39 溪流

说得挺中肯的,顶一下!  回复  更多评论   

# re: C++杂谈 2011-07-11 11:51 fx

代码还是实用点,简单点的好。  回复  更多评论   

# re: C++杂谈 2011-07-11 11:56 fx

智能指针上有点略微不赞同,一个大型软件项目,参与者众多,水平参差不齐。不用智能指针的话,太容易有内存泄漏了。教科书的受众,更多的是水平普通的开发人员,而不是小部分的C++精英。  回复  更多评论   

# re: C++杂谈 2011-07-11 12:00 华夏之火

大多数的内存泄漏,都是设计上的缺陷@fx
  回复  更多评论   

# re: C++杂谈[未登录] 2011-07-11 21:08 kevin

这篇文章只是暴露出了你的弱点。因为不能掌握C的细节而畏惧,对BOOST不了解而对其嗤之以鼻。C++因为先天缺陷其最大的障碍是如何对问题解偶,BOOST在这方面是典范,不仅提供了一系列的解偶工具,其本身也是一个很好的范例。多花点时间磨练一下自己吧。  回复  更多评论   

# re: C++杂谈[未登录] 2011-07-11 21:38 杨粼波

一切遵循木桶效应,如果项目中有一两个水平低的,那么整个项目的质量都可能会被这一两个人所拖累。

如果一个人,掌握不了复杂的东西。风险最小原则,那么就不要使用复杂的东西,那将会把一切都搞砸掉。

不论是什么语言,什么技术,在技艺好的人手里,都能玩转自如,而在一个初学者,一个愚笨者手里,任何东西都会弄得一团糟。

c的好处,对我来说,就是可以平铺直叙,只要设计好数据结构,就可以写算法了,很简单。c++这些有oo的语言里面,你却需要去做一些OO设计,但是如果设计好了,那就很舒服了,因为所有细节都被遮挡住了。

在我学习的那么多语言中,各种语言有各种语言的特色特点,同样也有他们的缺点。语言本身没有错,存在的就是有理的。错的,永远都是使用语言的人。

工欲善其事,必先利其器。没有那把金刚钻,就不要揽那瓷器活。  回复  更多评论   

# re: C++杂谈 2011-07-11 21:57 pangzi

auto_ptr<int*>,细节是魔鬼,尤其是写C++程序。  回复  更多评论   

# re: C++杂谈 2011-07-11 22:42 放屁阿狗

我考虑用c++无非是执行性能和写代码可以偷懒(比c),其他场景用脚本比较多  回复  更多评论   

# re: C++杂谈 2011-07-12 08:51 华夏之火

在下并不畏惧用C来开发,C的细节并不多,大部分语句,本人已有其对应的汇编代码的条件反射。在下对BOOST也没有嗤之以鼻。实在不明白阁下怎么对在下的误解会如此之大@kevin
  回复  更多评论   

# re: C++杂谈 2011-07-12 09:03 华夏之火

很有道理,完全赞同。语言自然没有错,用汇编都可以写出很优秀的软件,更何况是用C,只不过用C来开发,不仅仅只是设计数据结构和算法,还有更多问题要考虑,C胜在其简单,败也在其简单,当然对于高手来说,这些都不是问题。C++自然很复杂,我相信任何一个人都可以掌握复杂的东西,但问题在于要用复杂的工具来简化复杂的问题,而不是使原本就很复杂的问题变得更加复杂,至于OO等设计,不提也罢@杨粼波
  回复  更多评论   

# re: C++杂谈 2011-07-12 09:07 华夏之火

只考虑执行性能和写代码可以偷懒,这种态度对C++不公平,也会导致一些项目的问题,C++有属于自己的一套哲学角度@放屁阿狗
  回复  更多评论   

# re: C++杂谈 2011-07-12 09:09 华夏之火

细节确实是魔鬼,用C++开发,一定要花部分精力来专门对付细节,以方便其他地方,尽量避免接触细节@pangzi
  回复  更多评论   

# re: C++杂谈[未登录] 2011-07-12 12:13 tom

@pangzi
"auto_ptr<int*>,细节是魔鬼"
You are the best!  回复  更多评论   

# re: C++杂谈[未登录] 2011-07-12 17:22 Chipset

auto_ptr简直就是垃圾,多CPU环境怎么并发?还有,怎么弄个数组出来?
boost架构上尽管内部耦合很大,但无可厚非是一个优秀的C++库。
至于C++教材,50%起到正面作用,50%起到负面作用,尤其有些像什么谭xx的,简直就是误人子弟,除了考试纯属扯淡。  回复  更多评论   

# re: C++杂谈 2011-07-12 17:44 华夏之火

这样指责,有点冤枉auto_ptr了,auto_ptr旨在管理单个的对象,数组是其他智能指针的事情,至于多CPU环境,那对auto_ptr的要求也太高了,很多优秀的class都无法胜任。在下没有说boost不优秀。C++教材其实也很难编的,小强就不要说了,提都不值得提@Chipset
  回复  更多评论   

# re: C++杂谈[未登录] 2011-07-13 00:08 kevin

@华夏之火
从特定的角度来看文章表述的观点是没有问题的。但是没有考虑在复杂生产环境下的情况就把boost甚至C++0X标准拍死了。

试想一下,在高并发网络服务器上管理客户端连接(session),当一个session断开时,为了保证程序不异常不能立即delete掉session的内存,要先遍历一次消息队列,确定没有这个session的消息在等待处理才能释放内存,否则把session放到另一个队列等待它的所有消息处理完成后释放内存。想想这里的开销吧,是很惊人的。如果用shared_ptr来管理session,大可直接将session移出session队列,此session的引用计数不为0不会被释放,当消息队列中session的消息处理完成后引用计数归0,session自动delete,安全高效,是不是很爽?

一个大项目改动一个类或结构定义引起的连锁效应是很恐怖的,特别是在没有搞好前置声明的项目里,改个定义要把几乎所有文件重新编译一编,花十多分钟的时间,简直是个噩梦。这时候你会发现tuple是个多么美妙的东西。

functor、any等boost提供的工具都使c++变的更强大。

。。。越写越多,再写就快变成博文了。  回复  更多评论   

# re: C++杂谈 2011-07-13 09:28 华夏之火

再次声明,本人并没有拍死BOOST,至于看不起C++0X,那更属子虚乌有(此罪名是否Tuple、share_ptr在TR12中)。每一个类写得再不好,都有其应用的场合,更何况BOOST中的东西。高并发网络服务器,用share_ptr管理SESSION,确实不错,但有多少人需要写高并发网络服务器的,此种高端的东西,更要有高水平的人来做,相信除了share_ptr,还有更好的方案,比如SESSION POOL。至于tuple,依然无法解决重新编译的问题,返回tuple的时候,如果tuple中的类型改变了,所有使用到返回tuple的函数,还不是要重新编译。@kevin
  回复  更多评论   

# re: C++杂谈 2011-07-13 11:59 kevin.c

@华夏之火
session pool在这里解决不了问题,再仔细考虑一下吧。
tuple改变只要重新编译连接source文件就可以了,引用到header文件的其它类是不受影响的。  回复  更多评论   

# re: C++杂谈 2011-07-13 12:44 陈良乔——《我的第一本C++书》

很赞同你的关于C++教育的观点
我就很反对那种孔乙己式的搬弄C++语法细节的方式,所以我的书中,只介绍最常用最通用的问题的解决方法,不去向读者介绍那些所谓的高级技巧

另外,我的书中也涉及了智能指针,按照你的说法,应该算是一本合格的C++书  回复  更多评论   

# re: C++杂谈 2011-07-13 16:13 华夏之火

@陈良乔——《我的第一本C++书》
你的书通俗易懂,非常好,不仅仅合格而已,要是当初学编程时能看到这样的书就好了。我的第一本程序书居然是小强的C语言,唉,悲剧……  回复  更多评论   

# re: C++杂谈[未登录] 2011-07-14 20:45 cexer

应用的框架到了比较高的阶段,所面临的问题的宽度和深度已经完全超越了语言之间的微妙界线,所以像 shared_ptr 这类语言底层的东西,不能拿到这种场合来说。boost 是个大杂哙,有些东西用起来很不错,比如说 shared_ptr,有些东西不是拿来用的,是实验室产物,像你说的 tuple 确实是不大实用。
上面有人竟然拿 auto_ptr 来说多 CPU 并发。这种问题就好像,你在路上捡到一块鼠标垫,然后就开始发愁,还配点啥才能玩上魔兽世界。  回复  更多评论   

# re: C++杂谈 2011-07-15 08:49 华夏之火

@cexer
高手啊!只是近来颇为反感BOOST中的种种精巧的玩意,搞得大部分人对C++望而生畏。其实不搞花招,完全可以用C++写出非常清晰的代码。只要用上了花招,我就会怀疑那些代码的设计是否有问题,有必要那样拐弯抹角吗  回复  更多评论   

# re: C++杂谈 2011-07-17 18:34 nohacler

@陈良乔——《我的第一本C++书》
很幸运这本书算是我的第一本......其实我是看到很多注解才买的要不我就买小强的了 那就要杯具了  回复  更多评论   

# re: C++杂谈 2011-09-14 14:38 ToddChan

不思进取  回复  更多评论   

# re: C++杂谈 2012-05-25 21:23 幻の上帝

博主阅读水平或眼界堪忧……
《我的第一本C++书》比谭X好不了多少,在CU上早就被吐槽成蜂窝了。。。
  回复  更多评论   

# re: C++杂谈 2013-11-18 17:59 岁月漫步

写的很好  回复  更多评论   

# re: C++杂谈 2014-12-06 23:04 hancmhi

auto_ptr<int*> pa(new int) 是这样的吗?  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


导航

统计

常用链接

留言簿(6)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜