`
chinamming
  • 浏览: 151240 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

ATL、MFC、WTL CString 的今生前世

 
阅读更多
话说CString这个东西困扰了很多年轻人,因为它会引起诡异的编译错误,今天跟着我一起来深入ATL、WTL头文件,来把这个东西搞个清清楚楚。

涉及到头文件

  ATL: atlstr.h, atlsimpstr.h

  MFC : cstringt.h、afxstr.h

  WTL : atlmisc.h

  ATL和MFC有关剪不断理还乱的关系,为了更容易分析,我们先要理清这四个头文件间的关系。观察相互间观察顺序,可以得出:

  atlstr.h引用cstringt.h,cstring引用atlsimpstr.h,afxstr.h引用cstringt.h,由此可得出下图:

atlsimpstr.h 都干了什么

  1、定义了 CStringData 和 CNilStringData 类(前篇已述,此处略)

  2、定义了 ChTraitsBase 类,类如下:

  此类比较简单,功能是为不同的字符类型,建立新的统一的名称。另外,这里使用到了模板特化技术。

3、定义了CSimpleStringT类,此类的功能是,在ChTraitBase定义的统一名称的基础上,提供字符串一些基本的操作功能函数。

  

   t_bMFCDLL可无视。另外,注意,此处所操作的字符串对象,都是CStringData(前篇已述)

  总述:在atlsimpstr.h中,我们发现了3个令人感兴趣的东西,CStringData 是字符串操作单元,ChTraitBase提供字符串变量统一命名服务,而CSimpStringT是一个基于CStringData字符串操作单元的简易的CString(注意,只是简易,其中并未提供我们常用的CString中的那些函数)。

cstringt.h 都干了什么

  1、定义了 ChTraitsCRT 类,如下:

  

  该类继承atlsimpstr.h中的 ChTraitsBase 类,然后在父类提供服务的基础上,提供一系列字符串底层操作函数。思考:为什么此处用继承?而CSimpleStringT使用提typedef?

  2、定义了 _MFCDLLTraitsCheck 类,如下:

  

   这里再一次用到了模板特化技术,该类用于检测当前使用的StringTraits是ATL定义的还是MFC定义的。(ATL定义的叫StrTraitATL,MFC定义的叫StrTraitMFC,后面会提到)

  3、定义了 CStringT 类,如下:

  

   注意了,CStringT 就是CString的真身!前面说到,CSimpStringT操作CStringData字符串操作单元,提供基本的字符串操作功能,而CStringT继承CSimpleStringT,利用StringTraits,包装更高级的功能函数。而这些更高级的功能函数,就是我们通常调用CString时所使用到的那些函数。

atlstr.h 都干了什么

  1、定义了 CAtlStringMgr 类。(前文已述)

  2、定义了 ChTraitsOS 类,如下:

  

  和 ChTraitCRT相对应,ChTraitsOS继承atlsimpstr.h中的 ChTraitsBase 类,然后在父类提供服务的基础上,提供一系列字符串底层操作函数。

和 ChTraitCRT相比,他俩提供的函数大部相关,少数不同,另外相同函数名的实现不一定相同。

  3、定义了 StrTraitATL 类,如下:

  

  和 StrTraitMFC相对应,该类提供字符串资源管理函数和CStringData内存管理器的ATL版。

  4、定义了CSTRING,如下:

  

afxstr.h 都干了什么

  1、定义了 StrTraitMFC,如下:

  

  上文已述,和StrTraitATL相对,本类提供的功能实现都封闭在MFC中。

  2、定义了CString,如下:

  

atlmisc.h 都干了什么

  打开atlmisc.h,可以发现此文件只不过是定义了一些结构体,定义了一个CString的简易版。因为ATL CString依赖于MFC头文件,所以,如果在使用CSTRING而又不想加入过多其它文件时,WTL CSTRING提供了一个很好的选择。

  所有文件都分析后,我们发现,atl、mfc、wtl分别定义了一个CString。其中atl和mfc中的CString都是基于CStringT,只有一个地方是不同的,即CStringT所引用的StringTrait(即StrTraitsATL 还是 StrTraitMFC)。而WTL CString 的实现是独立的,是一个真正的类。另外 ,StringTrait引用的Iterator是可选的(即底层字符串操作封装)。

上文分析了ATL、MFC CString的设计和实现,我们不禁会疑问,为什么ATL和MFC的CString头文件要搅在一起?

上文的分析有些杂乱,我们通过一张图来更加清晰的观察,如下:

  上图中,用圈圈住的头文件表示ATL头文件,没被圈的代表MFC头文件。另外,在头文件旁边字符,表示各个头文件中实现的类。

  现在让我们仔细观看,整个貌似平衡的设计中,其实有着很多的不平衡。我想问:

  1、为什么MFC头文件cstringt.h要包含atl头文件atlsimpstr.h?为什么ATL头文件要包含cstringt.h?ATL搞ATL的,MFC搞MFC的,各不相干,起不更好?

  2、ChTraitOS 放在 atlstr.h 中,而 ChTraitCRT 放在 cstringt.h中,他俩功能是类似的,逻辑上是相对的,为神马在文件层次上却不对齐,要如此的别扭?

  话说中国人看待问题的时候,往往把某一大类看作一蹴而就的完美的整体。譬如Tencent很赚钱,很大,产品推出快,人们就认为Tencent内部有着良好的组织架构。这里我要告诉大家的是,任何大规模的东西,都是一点一滴积累起来的。ATL也是,MFC也是。这两个东西不是一个月、两个月的开发就成了现在的样子的,他们都是逐步叠加,逐步改进才成了今天这个强大的库的。扯了这些,是要告诉大家,要以变化、积累、动态来看待和分析事物的衍生。

  好了,现在我们来看为什么微软会搞出这么别扭的结构。

  话说,某一天ATL开发小组发现老是操作char,太低效,STL的string也不是很好用,于是乎,他们做了一个为ATL服务的简单的字符串类,名字叫 CSimpleStringT,通过typedef,定义成了 CSimpleString。

  后天某一天,MFC的人也发现char和string超不好用,他们发现公司的ATL小组已经做了一个成熟CSimpleString类,于是MFC小组拿来直接使用。在使用中,MFC小组的人发现CSimpleString做的太简单了,有很多的功能,它都不提供,另外,类函数设计的也不好用。于是MFC小组的成员决定扩展CSimpleString,他们将扩展的代码写进cstringt.h中,另外抽离出对外的接口头文件afxstr.h,将定义放在了这。(到这里,我们发现了上面提到问题的发生点,MFC的头文件继承了ATL头文件)。

  又到后来,MFC小组的某个成员(主程级)转到了ATL小组,来到ATL小组后,他发现,平日用惯了CString,现在要用CSimpleString真TM憋屈,于是他建议在ATL中自封装一个CStrnig。ATL小组发现,继然MFC的CString已经做得这么成熟稳定且好用了,自己没必要再另起炉灶,另外,他们发现cstringt.h是独立于MFC其它文件的,虽然属于MFC小组(MFC小组所写),但是引用的却都是atl的头文件,因此,引用cstringt.h不会融入MFC其它旁大的文件,因此可行。所以综合以上考虑,ATL小组直接继承于cstringt头文件,派生了自己的CString,放在了atlstr.h中。(注意,连名字取得都和afxstr.h相对应,到这里,我们又看到,ATL头文件继承了MFC头文件)。

  就这样,诞生了两份CSring。日子很平淡的一天一天过去,直到有一天,有个项目要混用ATL和MFC,他们发现,有两份CString,编译不过!因为ATL的CString毕竟只是模仿MFC,于是ATL让路,加上了宏定义 #ifndef _AFX ,意即,在没有使用MFC时,ATL才定义CString。

  ATL 和 MFC CString的故事讲完了,相信大家对CString相关文件目前结构的来龙去脉应该很清楚了。但是WTL呢?为什么WTL也要定义一个CString?话说WTL编写过程中,WTL组的后生小辈们看了ATL的CString代码,他们觉得咋这CString搞得咋这么复杂呢?看得头都大了,于是他们设计了一个四两拨千斤的CString,不继承任何东西,不依赖任何东西,就是一个简简单单的类。在初期,他们工作得很好,但是到后期,他们发现,如果两个人的代码用的是不同的CString的话,那么将代码合并的时候,编译不过,和之前遇到的问题一样,会产生两个CString,于是WTL不得不加了另外一个宏 _WTL_NO_CSTRING 来禁止WTL CString的编译。

  好了,故事全都讲完了,ATL、WTL、MFC,结论是,先有CAtlSimpleString,后有MFC CString,再有ATL CString,最后有WTL CString,唉,微软的人搞这么复杂干嘛呢……

  现在,还遗留一个问题,WTL、ATL、MFC,哪个CString效率高一些呢?欲知结果,待哥下回分析。

分享到:
评论

相关推荐

    WTL Makes UI Programming a Joy, Part 1: The Basics - Samples

    Even in ATL 3.0, there is no support for such popular features as MDI, command bars, DDX, printing, GDI, or even a port of the most beloved class in all of MFC, CString. Without these features WTL ...

    WTL起步-玩转图形界面

    自ATL 2.0版本开始,虽然ATL提供了一些简单的封装类,如`CWindow`、`CWindowImpl`和`CDialogImpl`来处理窗口相关的Win32 API调用,但相比MFC所提供的丰富的界面编程支持而言,ATL显得相对简陋。 #### WTL的发展背景...

    WTL简介WTL简介WTL简介

    6. **运行时依赖**:MFC通常需要动态链接库MFC42.DLL,而WTL可以减少这种依赖,甚至不需要CString也可以。 **使用WTL** 使用WTL开发时,可以通过安装的WTL SDK中的向导文件AtlApp60.awx来创建新的WTL项目。这个...

    WTL doc

    在ATL 3.0中,仍缺乏如MDI(多文档界面)、命令栏、DDX(数据对话框交换)、打印、GDI支持,甚至最受欢迎的MFC类CString的移植。因此,对于大多数MFC程序员来说,WTL并不能满足他们的需求。 WTL正是ATL团队认为窗口...

    WTL起步-玩转图形界面.pdf

    与MFC (Microsoft Foundation Classes) 相比,WTL提供了更简洁、更高效的接口来实现Windows应用程序的用户界面(UI)。 #### 二、WTL与MFC的功能对比 **1. 库依赖性** - **MFC**: 需要MFC库和CRT库。 - **WTL**: ...

    WTL 支持最新版 vs2010

    3. **预处理器定义**:在VS2010中,为了确保WTL和 ATL 的兼容性,可能需要在项目的预处理器定义中添加特定宏,例如 `_ATL_NO_PROTOTYPES` 或 `_WTL_NO_CSTRING`,这取决于你使用的WTL版本。 4. **调试与调试工具**...

    WTL tutorial

    WTL的初衷是为了弥补ATL早期版本在窗口类功能上的不足,尽管ATL自2.0版本起就有了如CWindow、CWindowImpl和CDialogImpl等简单的窗口包装类,但与MFC(Microsoft Foundation Classes)相比,这些功能仍显得较为简陋。...

    WTL-Developer-Guide

    WTL中的`CString`类提供了一种类似于MFC中同名类的字符串处理方式,但在实现上更加精简和高效。`CString`支持基本的字符串操作,如连接、查找、替换等,同时也支持Unicode编码。 #### WTL图形支持 WTL还提供了图形...

    WTL 8.1 界面开发库

    WTL 是 Windows Template Library 的缩写,由微软的ATL(Active Template Library) 小组开发,主要是基于 ATL 对Win32API 的封装。从 2.0 后,功能逐步完善,成为了一个完整的支持窗口的框架(windows framework)。 ...

    WTL起步-玩转图形界面

    CString是ATL/WTL中常用的字符串类,它提供了丰富的字符串操作方法。此外,WTL还包含其他实用类,如内存管理、事件处理等。 **第十一章 动态数据交换(DDX)的WTL支持** DDX是MFC中用于在对话框控件和对话框数据...

    MFC Widnows程序设计

    14. MFC与ATL/WTL结合:简述如何将MFC与Active Template Library (ATL)或Windows Template Library (WTL)结合,以增强性能和灵活性。 通过学习《MFC Windows程序设计》这本书,读者将能够熟练掌握MFC库的使用,从而...

    ATL实现的CDHtmlDialog模板类

    另外为了通用性以及减少依赖,代码中完全未使用CString或CAtlString,主要是MFC、ATL、WTL各自提供了自己的CString实现。 <br>版权特别声明:本软件源码完全属作者James(胡柏华)自创,作者拥有修改和变更代码...

    WTL图片框

    #include <atlmfc\atlctrlsw.h> #include class MyDialog : public CDialogImpl { public: BEGIN_MSG_MAP(MyDialog) // ... END_MSG_MAP() LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, ...

    C++字符串完全指南.doc

    WTL(Windows Template Library)的`CString`类与MFC的`CString`类似,但更轻量级。 2.4.9. CLR 及 VC 7 类 在.NET框架下,`System::String`是C++/CLI中的字符串类,提供了.NET特性的支持。 2.4.10. 字符串类的...

    WTL文件过滤器字符串对话框

    WTL是基于 ATL(Active Template Library)的,提供了对Windows控件、对话框、窗口类等的直接访问,为开发者提供了更简洁的接口。在创建文件对话框时,WTL提供了类似MFC(Microsoft Foundation Classes)的用法,...

Global site tag (gtag.js) - Google Analytics