MFC,一开始就错了_第1页
MFC,一开始就错了_第2页
MFC,一开始就错了_第3页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、MFC ,一开始就错了MFC ,一开始就错了谨以此文祭奠过去多少年下来,日日夜夜学习MFC源代码的宝贵时光。曾经以为MFC 是世界上最神圣无比的东西,发誓在没彻底弄透MFC 之前,绝不越雷池半步,碰都不要去碰LISP 、ERLANG 、PYTHON 、VCL 、ATL 、STL 、LOKI 、BOOST各种美妙的好东西。即使一再听到高人说MFC 设计得不好,非常糟糕,也都至死而不悔,然后只要稍微听到有人在说MFC 的伟大, 心里就特别高兴。买了各种各样的VC 方面的书,什么四大天王、什么几十百千例、什么VC项目实例,彻夜苦读,单步调试,一次又一次地徘徊在MFC套来套去的各种美妙代码之中,观察里

2、面各个对象的值。一次又一次地感叹 MFC 的伟大,一直在想,这辈子,如果能彻底地掌握 MFC 里面的一切秘密,朕就心满意足了。终于有一天,终于彻底醒悟,原来 MFC 真不是好东西,不过就是那些伎俩而已,真不该将它看得如此的伟大。这种念头一起来,再回过头来看 MFC 的一坨一坨代码,只觉得清晰无比,又感觉代码之中充满了各种无奈。 接着再看看那些 VC 方面的书,除了四大天王还稍微有些可取之处,其他的任何一本,奇臭无比,没有一行代码经得起推敲,文笔也糟糕无比,其内容又一再重复,抄来抄去,真正是一本又一本的狗屎。感叹一下:这些书牺牲了多少宝贵的树木,又折磨死了多少读者的脑细胞,实在罪大恶极。在 MF

3、C 大河日下的当今的大环境之下,在下也不想对它落井添石,毕竟也在其上学到不少好东西,特别是阅读代码的能力,试问这么糟糕复杂的框架都可以精通,天下还有什么代码能看不懂(别自信满满,你敢碰BOOST 里面的那些奇技淫巧,匪夷所思的幻码吗)。但实在忍受不了躯体内另一个人日日夜夜,旦夕不停的诉求,兼之又一直恨铁不成钢,又为自己失去的青春阵痛不已。而VC2008 中 BCG的出现之后, VC2010 还依然保留着那些蠢笨无比的BCG 文件,不思悔改,终于让某彻底对MFC 死心了,这货没得救了。好吧,废话少说,赶紧进入正题。国内 C+ 界中一大侠说过,任何东西,都要先抓住其主干, 其他的一切细节, 都可以

4、留待以后慢慢补充, 否则,一开始就陷入细节,想跳出来就不容易了。大侠此语,实在有道理。(不知为什么,此大侠后期一直在对C+ 表示不满,当然,人家现在的境界,岂是我等小民所能体会) 。不说其他,就说在 C+ 中,必须站在一个高度上,纵观全局,才能将一切看得通通透透。于是,下面就尝试爬上高峰,来俯瞰 MFC 中的众生。 MFC 的主干,在下看来,既不是什么六大关键技术, 也不是什么文档视图结构, 更不是 COM 的封装,而是为了将原始的 API 中的各种对象,好比窗口、 GDI 、设备环境等,都映射成相应的多线程安全的 C+ 对象,好比将 HWND 搞成 CWnd ,以期减轻 WINDOWS 下界

5、面开发的工作量。这种想法,其实也无可厚非,如果真能封装得好,确实可以提高生产代码效率,但是从C+ 和 WINDOWS 的设计观念中来看,这种映射,还是存在很大的问题,稍后再述。问题在于, MFC 的实现,异常丑陋呆板,通过几个全局的线程安全局部变量的映射表,将句柄(Handle,此词译得相当令人恶心)与其相应的C+ 对象指针形成一一对应,并且指定,在大部分的消息处理和参数传递中,所有的参数由原本的句柄一律由对象指针来代替,然后就高高兴兴地宣称已经完成任务了,这实在让人哭笑不得。不说别的,即使是消息处理, MFC 即使已经做了很大的努力,也都无法将句柄参数搞成对应的对象指针,单是这一点,就已经失

6、败了。然后再看看,它最后封装的做法,不过是将API 函数中的第一个参数为句柄的都改成相应的C+ 对象的函数成员,好比将SetWindowText 搞成 CWnd:SetWindowText ,美其名曰,薄薄的封装。 这真是要笑掉大牙了, 既然是这样的薄薄的封装,那还干脆不如不封装了, 我想破了头, 也看不出这样的封装,带来了什么样的好处。反而将原本全局函数的各种灵活性,都给葬送在类成员函数这个监狱中。全局函数的各种好处,除了是全局这个缺陷之外,实在都是类成员函数没法比的。而且,鉴于 API 中数量实在太多,于是搞出来的 C+ 对象都是庞然大物,最臭名昭著的,当然要数 CWnd 和 CDC 这对

7、黑风双煞了,使用起来,极不方便,极难学习。一个类的函数过多,无论如何, 都是失败的设计。 还有,如果 WINDOWS 系统新增了什么使用到句柄的函数,这些类也都要相应地增加新成员函数,再进一步说,如果用户自己因为需要,也要开发使用到句柄的全局函数,要怎么想办法整成员函数呢。其实, MFC 中的所谓的线程安全, 其实也不过是自欺欺人的说法而已,你要想在 MFC 中多线程的使用窗口对象,即使不是不可能,那也要花费九牛二力气才能在多线程中共享窗口对象,一切皆只因 MFC 已经很努力地做到了不让你在多线程下使用窗口对象。好了,再进一步考察,在这种思路的指导下,最后MFC 被设计成一个什么样的框架。一直

8、很怀疑想,MFC 的设计者,是否不是对WINDOWS API的精神了解得不透彻,又或者对 C+ 不是很精通,否则,无论如何,断断都不会整出 MFC 这样的一个人不象人、鬼不似鬼,精神分裂、做事虎头蛇尾的鬼东西出来。要不然,我们用MFC 开发,就不会觉得束手束脚,很不好施展拳脚,一再感觉一直受制于其可恶的呆板的框架之下,这并不是说框架不好,只是MFC这套框架,实在很不好扩充。这样也罢了,问题是,MFC 在使用上,又很不人性化,你又要陷入各种各样的细节之中,什么二段构造,有些对象又要自己删除,有些又不能自己删除等,更要命的是, MFC 的运行效率又臭名昭著。有些同学就会问,貌似在MFC 开发,其实

9、也很强大很灵活,殊不知这种强大和灵活,那都是源于C+ 的强大灵活,也源于WINDOWS 系统的强大灵活,源于MFC 只对 API 只作了一层薄薄的封装,与MFC 本身的设计没什么太多的关联。当抛开 MFC ,直接用 API 和 C+ 来写代码,就体会到什么才叫做强大灵活,除了代码比MFC 多一点之外,一切都要比MFC 来得清爽, 也要来得容易维护。 如果,如果设计做得好,可能总体的代码量不会比用MFC 的多也说不定。于是,这么一个伟大的框架,表现出来的,很多地方都 C+ 的精神格格不入。承然, MFC 刚开始设计时, 缺乏太多的 C+ 的特性的支持,而不得不另起炉灶。但是,就算没有 C+98

10、中的功能支持,MFC 也不该出现以下这么重大的设计问题。1、 不需要用到的特性,我们依然要付出种种代价。我们看到 CCmdTarget 集成了 COM 的功能, CWnd 中对 ActiveX 的支持,就算我们的代码不包含一丁点使用到COM 的代码,我们都要背负每个CWnd 中将近 100 个字节的大小, 运行过程中一再要忍受框架代码中对ActiveX 变量的一次又一次地检查。我们看到,就算不使用文档视图结构,CMainFrame中都要承受对它的支持代码,和各个不必要的成员变量。总之,MFC 中有很多特性, 就算不愿意使用, 它们还是在那里,不容许我们忽视。2、 耦合太厉害。我们看到, CWn

11、d 中居然出现了对子类 CView 和 CFrameWnd 的引用, CControlBar 的成员函数中有对 CToolBar 的 CAST ,然后, CFrameWnd 又引用到CControlBar 和 CView , CControlBar 和 CView 也都用到 CFrameWnd 的函数,各种各样好厉害的循环依赖, 这么糟糕的设计竟然出现在 C+ 的著名的界面框架,不得不令人叹息不已。这样的耦合,就是在MFC 之中,一个类设计得再好,也只能在某些特定的场合下使用。好比,CControlBar,CSplitterWnd 这两个好东西只能活在CFrameWnd ,CView 的环境下

12、,想在其他的地方使用上就煞不容易了。就算是著名的文档视图结构,也都是问题很大,如果我的类,想要订阅文档中的通知消息,还要求必须派生于CView 中,这个限制也太厉害了,于是为了它这个死板的设计,有多少次,我们必须改变设计,以适应MFC 的无理取闹的要求。3、 功能太过单薄: MFC 仅仅是作为一个界面的基本框架而已,仅仅实现了从句柄到对象的映射,然后,再加上一点点所谓的文档视图的MVC 模式,必要的多视图多子窗口的支持,基本的必要的COM 支持,对API 的薄薄封装,仅此而已(至于 SOCKET 、WININET和数据库的MFC 类,又有多少可利用的价值) 。有多少次,我们想对对话框进行拉伸的

13、操作;有多少次,我们需要用到表格控件; ,但是,这一切,想要MFC 提供更加强大的控件,完全都没有。必须求助于第三方控件公司库,好比,BCG 、XTREME ,你们知道,MFC 的代码就算再烂,也还是很有分寸,还能保住最基本的底线,但是,第三方控件的代码,那真的是,让人大惊失色,没有做不到的,只有想不到的。要知道,C+ 可是很强大的,但是,用它做出来的框架,却如此的功能之小。4、 MFC 中的类的功能不单一,承载了太多的责任,导致很容易就出现了很多重复的代码:好比CCmdTarget 中原本只是为了可以处理消息,后来居然还兼具COM 的功能。又好比,CList, CMapPtrToPtr 里面

14、又都包含了内存池的实现代码,原本这些内存池的实现代码就应该剥离出来。5、 行为错乱,神经分裂,没有统一的接口,以至于使用起来,极易出错。很多地方,都努力地去做了,但是都做得不彻底。企图封装所有的WINDWOWS的界面的 API ,但无论如何,都做不到,而且它自己内部也都知道没办法做到,但它还要努力地去做。各种各样的问题,难怪MFC 的书那么多,没有一本可以作为面向对象的典范学习,即使四大天王,也不过只是没有那么恶臭而已。原来一切,皆只因为源头本就脏了。之前还以为, MFC ,还能算是一积心堆砌而成垃圾。总体设计,虽然确实糟糕透顶,但细微上看,还能做到让人击节赞叹,好比对于线程局部变量的封装扩展,消息映射表。 可是,即使局部代码的实现,也都充满了重重的缺陷。如果说 MFC 还有些可圈可点之处,VC2008 之后引进的 BCG

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论