Tekkaman

导航

 

话说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的类关系有些复杂,我希望画一个图来更好的描述各个类间的相互关系,这个图将放在下一篇随笔……

posted on 2011-04-20 17:35  Tekkaman  阅读(7686)  评论(2编辑  收藏  举报