新年碎碎念

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/CharlesSimonyi/article/details/42339407

        看看周围的同学,大部分是搞Web开发、移动应用开发的,并且都搞出了各种各样的成果。有的开发出了IOS游戏并提交到了苹果应用商店里,有的开发出了Android应用并参加了各种比赛,有的在老师的带领下参与老师接到的商业项目做Web开发,而我这种搞C/C++/ASM的什么也参加不了。我们学校虽然不好,但是参与软件开发的机会还是不少的,学院的老师手里经常能接到项目让我们学生参与进来,如果能参与这些项目,无论是提升自己的编程能力还是给自己以后的简历增加一些内容都是很好的,不过这些项目几乎都是Web开发,和C++没什么关系,自然我无法参与。虽然我也可以开始学习PHP/C#/HTML/JS/CSS然后参与到Web项目开发中,但是一想既然当初选择C++就要一直走下去,不要东搞搞西搞搞,最后什么都会但什么都不精,并且大学精力有限,除了编程都还有很多很多事情要做,还有很多编程之外的知识要学。虽然说多学一些东西只有好处没有坏处,但也有一种说法是全才等于庸才,我还是更倾向于在某一方面深入下去,在某一个点上有所建树。就像《疯狂的程序员》作者绝影说的那样“要不就做第一个,要不就做最好的那一个”。

         话虽这么说,实际上深层次的原因还是不愿随大流,你想想,我又不是什么天才,如果我和大家一起去搞Web、移动应用,很难出类拔萃、成为佼佼者。特别是来读大学以后才发现牛逼的人太多了,有的人编程方面牛逼就算了,同时文化课程学习方面也牛逼,四六级轻松考下来,高数线代各种也无压力,奖学金各种拿,各种比赛各种奖各种拿,学生会、社团各种混得好,妹子各种泡。我当然没法和那些牛人比,索性干脆不要比,你在这个山头上混得很好了,我就不上来了,另找一个山头去混。其实就是有点宁做鸡头不做凤尾的意思吧。另外一个原因是我从小就比较喜欢琢磨原理性的东西,小时候的各种玩具尤其是电动玩具,总是喜欢把它们拆开看看是什么原理,并且自己琢磨着能不能效仿着自己制作一个。搞C/C++开发正和我心意,能和操作系统紧密接触,看一看它是怎么实现的,比如Windows上的窗口是怎么实现的,又是怎么运作的,EXE文件是怎么运行的,线程和进程究竟是什么东西,MFC里的那些类实现了的功能,如果用WinSDK又该如何实现。这点我和《疯狂的程序员》作者绝影很像,其实我之所以选择C/C++/ASM也是受这本小说的影响。记得第一次读这本小说的时候我还一点编程都不会,看了这本小说后非常佩服小说中的绝影,佩服那种程序员身上的疯狂劲。

       说着说着就扯远了o(╯□╰)o,虽然我不随大流,但看着同学们在老师的带领下混得风生水起,各种成果一项又一项,参加各种比赛拿各种奖项,而自己至今没有什么拿得出手的东西,心里不免有一丝丝浮躁。我所选择的领域确实是一个低不成高不就的领域。
       低是指底层,和硬件紧密接触的这一层,如嵌入式开发。嵌入式开发使用C语言,我虽然作为一个C++程序员,但要写纯C代码也并非难事,可是我并非嵌入式专业出生,没有学过硬件方面的知识,找了几本嵌入式的书看了下,果然,没有硬件方面的基础知识什么也看不懂。我们学院前几年有老师带领学生做嵌入式方面的开发,制作出了基于摄像头采集图像并分析处理的智能寻轨小车,参加比赛并拿了奖,不过现在几乎没有听说有嵌入式方面的项目了,现在学院的实验室大部分是搞Web开发、移动应用开发的。毕竟我所在的学院是软件学院而不是计算机学院,学院的主要方向还是应用软件开发,而且Web开发、移动应用开发都是当前最火热,需求量最大的方向,学院从这两方面培养学生,学生以后也好就业。
       高是指最上层的应用层。如果是在10年前,C++确实是开发应用软件的主力工具。那时候的C++各种通吃,Windows上的各种桌面应用软件基本上都是VC++或Delphi开发的。那时候的移动端,智能手机主流的 Windows Mobile、Symbian系统上的软件都是用C++开发的。还有什么导航仪、学习机等智能设备,那时候Android系统还没出现,大多是搭载WinCE系统,也是用C++来开发相应应用。而且WinCE上也可以用MFC框架,你能想象吗?MFC曾经可以拿来开发移动应用软件!总的来说那时候,PC端、移动端、服务器端、3D游戏等各方面都让C++占了,甚至Web开发方面C++都想来插上一脚,微软出的ATL Server就是个例子。那时候的C++程序员可谓混得风生水起啊。可是后来C++的开发范围被新出现的各种语言、框架蚕食。Windows桌面应用开发本来就因为移动端的发展而变得不景气,在这种情况下这方面的份额还被C#/Winform/WPF不断侵占,即使C++没哭,MFC也哭了,他爹微软都快不管它了。而移动应用开发方面被JAVA/C#/Objective-C占去了,除了移动端上的游戏开发,移动应用基本上和C++关系不大了。所以到现在C++主流方向只剩服务器开发和游戏开发了。总的来说就是现在的C++不太适合做上层应用开发了。其中的原因有很多,比如C++不像C#/JAVA那样下面有虚拟机,难以隔离系统特性(总是需要直接调用系统API),没有垃圾回收,没有统一、强大的标准库,背着性能要求和对C的兼容这两个包袱,开发效率不够高,语言复杂等。虽然C++不如以前那么辉煌了,但直到现在他仍然是一门主流语言,在语言排行榜上仍然排在前,再加上有C语言这个亲兄弟拉着它,个人觉得只要C语言不亡,C++也不会亡,如果C语言都灭亡了,JAVA/C#应该也不存在了吧。
       C++的开发范围虽然大量缩减了,但仍然是有出路,有前途的。一个是服务器开发,如游戏服务器,Web服务器以及各种云服务器上的服务端开发,这些服务端软件要求高并发,高吞吐量,高性能,所以用C++开发是个很好的选择。一个是游戏开发,PC游戏,各种单机游戏,网络游戏,还有移动端上的3D游戏。还有一个是系统软件开发,如杀毒软件、电脑管家、防火墙等,这些软件因为需要调用系统底层的接口,有的还需要开发系统驱动程序,而操作系统是C语言写的,和操作系统紧密交互用C++当然是最好的选择。另外就是多媒体方面的开发,图像、音频、视频处理,这些东西和游戏一样需要较高的性能,需要榨干电脑硬件的每一点性能,所以用C++来开发是个很好的选择。还有就是一些工控软件、上位机应用,因为要和嵌入式那边的C语言搭配合作,又需要在PC机这边有直观的界面,所以用C++/MFC开发是个好选择。

       出路是有,但这条路对初学者对应届生来说并不是那么轻松,比如一个学生学上一段时间的HTML/JS/CSS后,就能动手开发出一些像模像样东西,然后毕业去找Web前端开发方面的工作,由于这方面需求量比较大,门槛也不高,很容易找到相应的工作。而另外一个学习C++的学生就不一样了,这方面的招聘需求没有Web、移动应用的需求那么多,而且大多要求有工作经验,你想想你一个应届生能直接去参与公司的服务端软件开发吗?服务端是需要高稳定高性能的东西,而且涉及到很多方面的知识,多线程、多进程、内存池、Socket、数据库、Linux,随便一样都不是一个初学者能轻松掌握的。而且学C++的学生在学校里几乎接触不到什么项目,经验上更是一片空白,找工作时有难度啊。但也不是只有忧没有喜,如果C++程序员努力在服务端开发方面积累经验,有所建树的话,收入是相当高的。


       都说学C++的人要沉得住气,C++的初学者往往学了很长一段时间还是什么也搞不出来,而学Web开发、JAVA、C#等的初学者学一小段时间就能搞出像模像样的东西。这时候C++的学习者心里难免有些动摇、有些浮躁了,于是有的人就放弃了,跑去搞Web开发、移动应用开发去了。后来他们每学一段时间就能马上看到自己的成果,看到成果就有了动力,有了动力就容易坚持,再不断努力,结果当然是好的,前途一片光明。其实无论学什么、做什么,只要你努力了,坚持了,结果自然不会差。

       为什么C++的初学者往往学了很长一段时间还是什么也搞不出来,很大一个原因是C++这门语言非常复杂,在网上可以看到很多人说“C++是世界上最复杂的编程语言”,其实这样说一点都不为过。C++对面向过程、基于对象、面向对象、多范型等编程范式都支持,可伸可缩,可上可下,仿佛是什么都要支持,即使不能支持的,创造条件也要支持。C++里一个cpp文件里面,居然可以同时写四种语言的代码,纯C语言、C++语言、汇编语言、NET语言(C++/CLR),四种语言的代码可以写到一个函数里直接编译!很多初学者花了很长时间才学会了C语言,学会了面向过程编程。好了,接着又是C++面向对象编程,虚函数、多重继承、虚继承什么的都来了,内存还得自己管理。好吧,又学了几年,感觉面向对象编程差不多了,范型编程又来了,函数模板、类模板又够学好几年了,又学了好几年,好了,面向过程、面向对象、范型编程一起上又懵了。记得有一次我瞥了一眼ATL的源码,类模板的多重继承+类模板的嵌套定义,彻底绝望了其实关于C++复杂的这个话题网上有很多大牛已经反反复复的讨论过了,这里就不再多熬述了总之总的来说就是三点:1.复杂2.复杂 3.复杂

       另外一个原因就是类库、框架、开发工具的支持,C/C++虽然有非常丰富的第三方类库,但不像C#/JAVA那样有官方提供的统一、强大的标准库。所以C++程序员如果要想开发一个软件,很多时候都得东拼西凑的到处找第三方库,而第三方库大多文档不齐,有的甚至文档都没有!即使有文档也都是英文文档。再加上很多第三方库都是在Linux上开发出来的,拿到Windows上来,拿到VisualStudio里来编译,十有八九要蹦出一堆错误。这对初学者来说都是一个个大大的绊脚石。

       你可以想象这样一幅场景,一个C++初学者好不容易克服重重困难学会了这门复杂语言的语法基础,摩拳擦掌的准备开发一点实用的Windows应用软件了,拿过《Windows程序设计》来看,头都大了,一个基于WIN32窗口应用程序的hello world的代码都是满满一屏幕,什么消息循环、窗口过程、句柄,听都没听说过,于是又陷入了痛苦的学习中。照着书上的代码敲上去,一编译出错了,搞半天才发现是字符集问题,原来还有多字节字符集和宽字节字符串之分。学习了一段时间后发现有MFC这个东西,用来开发窗口应用程序会很方便。本来C++就够复杂了,MFC又是一个复杂的框架,该初学者又陷入了新的痛苦的学习过程中,各种消息映射宏、虚函数、各种消息、各种结构体。而且WinSDK、MFC在MSDN上的文档都是英文的,哪像C#的NET和Java的JDK,都有全中文文档,这时候初学者的脑袋又开始痛了。

       痛归痛,经过不断奋战MFC开始上手了,开发窗口程序确实比WinSDK方便了,但是MFC的封装层次确实不如C#的Winform。MFC封装得较浅,很多功能都没有封装,需要直接调用WinSDK中的API来操控控件,甚至需要对控件直接发送Windows消息来操控它,然后又要填充那一个个C样式的结构体。比如要在窗口上实现一个控件,类似于网页中的超链接。在C#中直接拖个LinkLabel上去就行了,而C++程序员就得自己实现了,弄个Static静态文本控件,响应一下WM_CTLCOLORSTATIC消息,把静态文本控件的文字设置为蓝色,然后响应一下WM_MOUSEMOVE消息,当鼠标以上去的时候把鼠标变成手型,鼠标移开的时候要恢复指针型,又要把静态文本控件设置成SS_NOTIFY样式,这样点击它的时候才能向父窗口发WM_COMMAND消息。好吧,这些处理完了,还要响应WM_COMMAND消息,调用ShellExecute打开那个超链接。全部写完了,运行了一下,恩,很漂亮很不错,不过这样代码太散了,以后复用也不方便,自己写个类封装一下吧,要怎么封装呢?恩,先学习一下,尝试着写一写,好不容易搞定了,虽然封装得比较拙劣,但也算像模像样了,给它取个名字ClinkStatic,放入自己的代码库。正在得意的时候,扭头一看,用C#开发的同学早就在写数据库读写的部分了。当然MFC新一点的版本里已经有CMFCLinkCtrl了,不需要自己写了,这里只是举个例子,实际上还有很多窗口上的控件,尤其是列表框那一类,MFC的封装层次确实不如Winform,开发同样功能的界面,MFC需要花的功夫比Winform多。

       又比如要实现窗口最小化到托盘,C#中只需要拖个NotifyIcon上去,然后写一下事件函数this.Visible = true;显示窗口,this.Visible =false;隐藏窗口就行了。而C++中需要调用API Shell_NotifyIcon,填充一个结构体NOTIFYICONDATA。天哪!这个结构体居然有15个数据成员,每个数据成员都没有默认值,需要写15行代码一一赋值,而且MSDN上的文档又是英文的,翻译那些英文都头痛,好不容易翻译过来了,问题又来了,UINT  uCallbackMessage;是什么?回调消息?怎么用?uFlags和dwInfoFlags这么多标志都是什么意思?干什么用的?我该用哪个而不用哪个?uVersion版本号?怎么还分版本,什么版本?GUID  guidItem;是什么,GUID是什么东西?HICON hIcon;图标句柄?图标怎么创建,怎么获得图标句柄?可怜的C++初学者好不容易百度加Google一点一点的搞懂(其实是半懂)了这些问题,并且经过不断的摸索和尝试,总算实现了窗口最小化到托盘,这时候看看一看外面天都黑了,一天就这么过去了,再看看旁边搞C#的同学,软件已经开发好了正在做测试...。

       总之简单来说用C#开发Windows窗口应用程序确实比MFC方便很多,你需要的控件基本上都有了,啪啪啪往窗口上拖,打开控件的属性看看都有什么事件,双击一下就开始写该事件的响应函数。每一个窗口、控件就是一个对象,直接“对象.XX属性=YY”就实现了改变控件的效果,如果需要访问控件内的元素,只需访问该控件对象的属性。比如ListBox,里面就有个Items属性,这个Items就是个ObjectCollection,提供了超多的方法,访问起来超级方便,你要Add()、要Clear()、要Insert()、要Remove()、要AddRange()、要它的Count,它都已经提供了,甚至还可以直接用数组下标来访问,“listBox1.Items[0]= "Hello";”“listBox1.Items[1] = 500;”用起来比C++中的Vector还爽。而MFC中的ListBox,哎,不说了,就给你个CListBox::AddString,反正每次只能添加一个字符串,你自己去琢磨吧...。C++初学者再一次流出了眼泪。说到底主要还是Winform封装层次高,提供的控件超级多,提供的方法超级多。

       说到这里不得不做一个有趣的假设,如果让一个一直在用Winform的C#程序员去用C++/MFC来开发Windows窗体应用程序,他一定会非常抓狂,怎么这也没有,那也没有,然后发疯似的把电脑砸了。如果你再让他去用Win32汇编来开发,哎呀,那可是一个库函数也没有啊,一个也没有啊!而且一个变量的赋值都得几条语句啊,我还是死了算了,哈哈。

       不管怎么说,C++初学者还是凭着顽强的毅力,艰苦奋斗的精神把该实现的都实现了,虽然比搞C#的同学慢了很多。那么接下来,无论MFC还是Winform做出来的窗口程序都是那个死板的样子,不好看。C++初学者和C#初学者都嚷嚷着说要把界面做好看,于是C++初学者开始看DirectUI,C#初学者开始看WPF,后来怎么样?怎么样就不知道了,只是听说C++初学者所在的宿舍在晚上总是传出凄惨的哭声。咳咳,当然这里只是开个玩笑啊。

       既然C#那么火,Winform和WPF开发Windows窗体应用程序那么方便,为什么还有人还在搞C++,还在用MFC?其实任何东西都有两面性,有好处当然也有坏处,用Winform和WPF的好处就是开发简单、开发效率高,坏处就是让程序员变懒惰了。哈哈,这当然是个玩笑,真实的原因是C#是微软用来和JAVA竞争的,它的定位已经很明显了,上层应用开发。

       举个例子来说,XX管理系统。比如大医院内的管理系统,收费处、药房、诊断室、住院部、CT站等处处都用上了电脑,如果用软件、网络、数据库把他们连接起来,医生就不用写字了,病人也不用拿着各种单子跑了。医生在电脑上开了药单,病人去收费处,收费处的工作员点一点鼠标,收了患者的钱,点确认,病人直接去药房取药,药房的工作人员点点鼠标,拿药给你。并且这些数据、病例都保存在数据库中,以后随时都可以方便查阅。此类XX管理系统在各行各业到处都有应用,需求量非常大,再加上各行各业都往信息化发展,小超市、小饭店也要用上信息管理系统了,可见其需求量只会越来越大。其实此类XX管理系统在10多年前很多都是用C++/MFC/Delphi开发的,但后来基本上都转向了C#、JAVA开发,因为用C#、JAVA开发确实很方便,这些XX管理系统的实现基本上就是只用到图形界面、数据库读写、网络通信这几项技术,这些技术在NET、JDK中都有很好的封装,用起来非常方便,开发效率很高。

       开发上层应用软件C#确实得心应手,但开发系统软件C#就力不从心了,比如各种杀毒软件、电脑管家、防火墙,这些软件需要调用的API都是操作系统比较底层的API,并且这些API在NET中都没有封装,而且很多时候还需要用C语言开发相应的系统驱动来配合工作,所以这方面的系统软件开发仍然是C++的强项。虽然C#也可以直接调用WindowsAPI,但是调用起来比较麻烦,每一个API函数在调用前都要声明一下,而且这些API都是C语言的接口,参数都是C类型,还有各种结构体,在C#中处理起来就变得很麻烦了。并且C#程序员长期做上层应用开发,和各种类打交道,各种类调来调去,难免对Windows底层的原理,程序运作的原理缺乏深入的了解。如果需要实现一些功能,如:向目标进程注入自己的dll,干预目标进程的行为,读写目标进程中的内存,向EXE文件注入自己的代码,拦截一些用户操作或系统操作,消息钩子,API Hook等,用C#来实现的话反而会变得很麻烦。所以这一块系统软件仍然用C++来开发,毕竟C#的定位摆在那里,没必要来和C++抢这一小块地盘。

       当用C++把系统软件的功能写出来以后,还缺个界面,这时商业公司一般采用DirectUI,因为DirectUI做出来的界面很漂亮。个人软件就不用那么讲究了,有界面就行,自然就用到了最方便的MFC。VisualC++中给C++程序员提供的GUI框架本来就只有这么个MFC,并且之前很多程序员都用得很顺手,毕竟MFC从诞生到现在已经有20多年了,关于MFC的资料、文章很多很多。MFC自然就成了Windows上C++程序员开发个人软件的首选GUI框架,直到现在也是这样。即便微软从VS2008以后就基本没有再更新MFC了,但直到用上了VS2015还是有很多C++程序员在用MFC。

       不过还是有些C++程序员跑到CSDN论坛问,MFC是不是过时啦?转战QT怎么样?我该怎么办?还是去搞Web、移动应用算啦?其实你应该明白你是一个程序员,或者说你是一个C++程序员,而不是一个MFC程序员。即便是MFC大有前景,你也不能光靠MFC来吃饭,毕竟MFC只是一个GUI框架,你作为一个程序员,难道你的核心竞争力就是掌握一个GUI框架的使用吗?我在网上看到过一句话,这句话我一直铭记在心里,这句话就是“作为程序员,你能做的,别人看了书也能做,这不值钱,你能做而别人不能做的才值钱!”。

       好像离题有点远了,言归正传,接着讲为什么C++的初学者往往学了很长一段时间还是什么也搞不出来的原因中的“类库、框架”原因。上面只是拿C#/NET来举例对比,Java/JDK和C#/NET差不多(应该说是C#/NET和Java/JDK差不多,毕竟先有的后者),JDK也是一个非常丰富、强大的类库,而且比NET还强大,具体怎么样就不细细对比了,总之你应该懂了。不过C++程序员也有笑的时候,很多第三方库,尤其是多媒体、游戏相关的库都是C/C++开发的。而且NET/JDK里提供的很多功能,C++程序员也可以通过第三方库来获得。但第三方库的使用对于C++初学者来说并非易事啊,于是头疼之路又开始了。

       这天,C++初学者和C#初学者都要做一个软件,这个软件可以从某彩票网站上采集下每期各种彩票的开奖数据来,然后把这些数据进行整理和计算,显示到窗体应用程序的界面上,这样便可以方便、快速、直观的浏览各种彩票数据,进一步再增加走势图绘制功能和一键下单买彩票功能。C#初学者开搞了,百度、Google了一下需要用到的相关技术,知道访问彩票网站获取数据,NET里有个System.Net.WebClient可用,获取到的HTML数据需要分析并提取出想要的彩票数据,可以用Microsoft.mshtml来解析HTML并提取想要的数据,然后就开始搞了。C++初学者开搞了,首先是访问彩票网站获取数据,百度、Google了一下知道有个libcurl的开源库可用,于是到libcurl官网上把它下载了下来,然后到处求教如何部署如何编译,好不容易添加到VS的项目工程里了,一点编译,哗啦啦啦啦啦啦啦,一大堆错误,吓傻了。然后跑到网上疯狂的搜索,求爷爷告奶奶,搞了一整天,好不容易没有编译错误了,看着VisualStudio的输出窗口显示“成功 1 个,失败 0 个”,心里顿时一片舒坦。殊不知,恶梦还没有开始...。libcurl是编译好了,生成了一个lib和一个dll,这个lib和dll是什么呀?怎么用?于是又跑到网上搜索答案,好不容易搞定了,心里顿时一片舒坦,殊不知,恶梦还没有开始...。紧接着开始看libcurl的官方文档,哎我去,全部都是英文。好不容易在有道词典的帮助下看懂了一些,写出了一个简单的例子,运行一下,获取到了HTML数据,心里顿时一片舒坦,殊不知,恶梦还没有开始...。突然发现libcurl好像不支持Unicode,哎呀,这可不好,自己所有的程序都是基于Unicode写的,不行不行。而且那英文文档也是看得很痛苦,而且这libcurl是C语言的接口,函数的样子也都是Linux风格,和WinSDK中的风格完全不一样,好别扭啊。搞了大半天,学会发送GET请求都很艰难了,还要研究如何POST,太痛苦了。还是看一看微软有没有提供这方面的类库吧。找了一下,发现WinSDK中提供了WinInet和WinHttp可以实现基于HTTP协议对Web服务器的访问,好吧那就用WinHttp吧,还是微软的东西用着舒服。看着MSDN上关于WinHttp的英文文档,在痛苦的翻译过程与不断的摸索中,总算成功发送了GET请求并获取到了HTML数据,心里顿时一片舒坦。殊不知,恶梦还没有开始...。这个WinHttp也是C语言的接口,调用起来比较麻烦,每个函数参数都要写齐了,一个都不能少,这么多参数,这么多宏定义,这么多结构体,都要去细细理解,每一个函数的调用都要判断好返回值处理好错误。结果代码写下来,就一个简单的GET请求,那代码都好长好长啊!不行,这样代码不能复用,也没有面向对象思想,得封装一下。于是喝了一杯鸡血,端坐在电脑前,新建了一个webclient.h和webclient.cpp,郑重其事的敲下了第一行“class WebClient”。

       三天过后,随着最后一行代码的完成,VisualStudio的输出窗口显示“成功 1 个,失败 0 个”。C++初学者顿时感觉到很满足,自己的WebClient虽然不能和NET中的WebClient媲美,但也有模有样,该有的都有了,拿在手上也来去自如,相当顺手,顿时心中一片舒坦。殊不知,恶梦还没有开始...。现在已经可以从彩票网站上获取HTML数据了,接下来要解析它并提取出数据来,如何解析呢?于是C++初学者开始在网上寻找答案。过了一会儿发现解析HTML的第三方库还不少,什么libhtml、Streaming HTML parser、htmlcxx、还有Google的Gumbo!不过C++初学者这次学聪明了,还是找找微软有没有提供这方面的库可用。找了一下发现了MSHTML这个好东西,看了MSDN上关于MSHTML的英文文档,发现这个MSHTML非常强大,于是在网上搜索C++如何使用MSHTML。后来发现这个MSHTML需要通过COM接口来访问,COM接口是什么东西?IUnknown、IDispatch、QueryInterface是什么东西?看到网上的示例代码还用到了CComPtr、CComQIPtr、CComBSTR,这些又是什么东西。百度科普了一下,发现前面那三样是COM里的东西,后面那三样是ATL里的东西。于是C++初学者找来了《COM本质论》、《COM技术内幕》、《COM原理与应用》、《ATL开发指南》、《深入解析ATL(第2版)》,然后津津有味的看了起来...。后来怎么样?反正后来C++初学者的软件确实在一场又一场的恶梦中开发出来了,不过那个时候C#初学者已经开始开发第六个软件了。

       也许你会问C#初学者用的不也是MSHTML吗?为什么很快就搞出来了?那是因为NET隔离了COM接口那些复杂的特性,根本不需要了解COM接口,不需要调用QueryInterface这些东西。在NET里引用了MSHTML后,MSHTML里面的接口就变成了一个个的C#类,直接XX xx = new XX();然后xx.yy = zz;方便的调用。至于CComPtr、CComQIPtr这些智能指针更是不需要,NET自己能回收垃圾。

       后来有一天,C++初学者和C#初学者都想开发一个读写Excel文件的软件。C#初学者淡定的写下了“usingMicrosoft.Office.Interop.Excel;”,然后各种XX xx = new XX();各种xx.yy = zz;来去自如。而C++初学者也淡定的写下了“#import "C:\\Program Files\\MicrosoftOffice\\Office14\\EXCEL.EXE"”,可是一编译就哭了,VisualStudio的输出窗口显示了上百个编译错误。后来C++初学者又投入解决该问题的苦海中...。

       再后来,C++初学者和C#初学者又开发一个读写数据库的软件,他们都决定用ADO。C#初学者淡定的写下了“using System.Data;”而C++初学者淡定的写下了“#import "C:\\ProgramFiles\\Common Files\\System\\ado\\msado15.dll"”,后来?后来怎么样?我就不说了,我已经哭了。

       为什么C++程序员那么苦逼,才#import把需要的东西包含进来,还没开始写代码,你就给人家整出几百个编译错误,人家还是初学者,什么都还不知道,刚准备写第一行读写数据库的代码,你就给他这么个下马威。非得让初学者把这些复杂的问题解决了,把这些东西的原理弄清楚了,才能开始写第一行从数据库里读数据的代码。

       再后来,C++初学者和C#初学者都准备开发一个DLL给别人调用。C#初学者淡定的新建了一个C#类库项目,写下了各种类,把DLL拿给别人后,别人using一下,然后各种XX xx = new XX();各种xx.yy = zz;来去自如。C++初学者淡定的新建了一个Win32项目,选择DLL项目。哭了,怎么Dll也有Main函数,这个DllMain是什么东西?DLL_PROCESS_ATTACH,DLL_THREAD_ATTACH,DLL_THREAD_DETACH,DLL_PROCESS_DETACH是什么东西?DllMain函数里我该怎么写?在网上找到一些示例代码后,问题又来了,_declspec(dllexport)、extern "C"、_stdcall、def文件是什么?为什么要用?怎么用?还有调用DLL后,内存谁来分配,谁来释放?DLL能不能静态链接到CRT运行库?静态链接会有什么问题?对了,CRT运行库是什么东西?越看头越大,于是C++初学者找来了《windows核心编程》和《程序员的自我修养——链接、装载与库》,又投入了万劫不复的学习中。学习N天后,对DLL大致都有了解了,想到自己的DLL需要用到MFC的一些类,于是打开VisualStudio,创建了一个MFC DLL项目,定睛一看,又哭了,怎么DllMain没了,这些宏是什么意思...。

       后来,还有很多后来,C++初学者和C#初学者还有很多故事,但是故事的情节都和上面差不多,所以我就不再重复了...。

       继续回到主题上来,刚才说到类库、框架,现在该说开发工具了,这里指的是编译器的IDE。C++当然也有很多强大方便的IDE,比如微软的VisualStudio,用起来非常顺手。不过在代码重构上,重构C++代码似乎比重构C#/JAVA代码难很多,这些优秀的IDE在重构C++代码上也显得不是很给力,至少没有重构C#/JAVA代码那样给力。也许C++代码就是那么复杂,让IDE读着都头痛o(╯□╰)o。另外就是编译器对C++语言新特性的支持,C++11、C++14的新标准出来以后,即便是VisualC++这样大名鼎鼎的编译器,对其的支持也是缓慢而滞后,并且有部分特性,很早就出来了,至今仍未实现(%>_<%),难道是因为太难太复杂了?当然,相对于前面那些问题,这个问题对于C++初学者来说根本不是什么问题。

       说到这里,你应该明白为什么C++的初学者往往学了很长一段时间还是什么也搞不出来,应该明白为什么有的初学者放弃了C++转而去搞其它,同时也应该对一个优秀的C++程序员肃然起敬。C++程序员那么多的困难都一路走过来了,以后还有什么好害怕的,这么多莫名其妙的问题都解决了,以后还有什么问题什么解决不了。

       说了那么多,总结下来就是C++难学,一路上坎坎坷坷异常艰辛,到最后就业还不如Web开发和移动应用那样广阔和火热。但仍然有很多C++程序员奋斗在这条路上,究竟是为什么呢?执着?信仰?不走寻常路?这其中的原因我还是放到若干年后再说吧!现在说出来你们都来搞C++,抢了我的饭碗怎么办,哈哈。

猜你喜欢

转载自blog.csdn.net/CharlesSimonyi/article/details/42339407