zl程序教程

您现在的位置是:首页 >  后端

当前栏目

深入分析:C++模板究竟会使代码膨胀吗

C++模板代码 究竟 深入分析 膨胀
2023-06-13 09:14:52 时间

今天和同事说到C++模板会使代码膨胀,可同事觉得不会。
同事的依据是:如果模板会使代码膨胀,那么ATL和WTL里为什么还要大量使用模板?同样功能,ATL和WTL编译出的可执行文件可比MFC编译的要小的多。
我当时一愣,事实确实如同事所说,难道模板会使代码膨胀的观点是错误的吗?

MFC因为本身代码量和复杂性在那里,所以它生成比较大的exe无可厚非。我们这里重点关注为什么ATL/WTL使用模板,但是却不会使生成的exe变大。

我们知道使用模板时,同一模板生成不同的模板实类后会是多份代码,比如vector<int>,vector<char>,vector<double>,这里总共会生成3份不同的vector代码,这就是我们平时所说的代码膨胀。

那么为什么ATL/WTL就没有代码膨胀的问题呢?
我这里以ATL里的窗口代码为例来分析这个问题,因为我对WinDbg比较熟悉,下面我会以WinDbg为工具来分析我以前的写得那个俄罗斯方块程序。

首先我们看一下ATL的窗口代码:

复制代码代码如下:

template<classT,classTBase/*=CWindow*/,classTWinTraits/*=CControlWinTraits*/>
classATL_NO_VTABLECWindowImpl:publicCWindowImplBaseT<TBase,TWinTraits>
{
public:
   DECLARE_WND_CLASS(NULL)

   staticLPCTSTRGetWndCaption()
   {
       returnNULL;
   }

   HWNDCreate(HWNDhWndParent,_U_RECTrect=NULL,LPCTSTRszWindowName=NULL,
           DWORDdwStyle=0,DWORDdwExStyle=0,
           _U_MENUorIDMenuOrID=0U,LPVOIDlpCreateParam=NULL)
   {
       if(T::GetWndClassInfo().m_lpszOrigName==NULL)
           T::GetWndClassInfo().m_lpszOrigName=GetWndClassName();
       ATOMatom=T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);

       dwStyle=T::GetWndStyle(dwStyle);
       dwExStyle=T::GetWndExStyle(dwExStyle);

       //setcaption
       if(szWindowName==NULL)
           szWindowName=T::GetWndCaption();

       returnCWindowImplBaseT<TBase,TWinTraits>::Create(hWndParent,rect,szWindowName,
           dwStyle,dwExStyle,MenuOrID,atom,lpCreateParam);
   }
};


上面是一个模板类,它应该会生成多份模板实例代码:我们可以用WinDbg的符号搜索命令来做验证:
输入xHYTeris!ATL::CWindowImpl<*,搜索所有以HYTeris!ATL::CWindowImpl<开头的符号
复制代码代码如下:

0:000>xHYTeris!ATL::CWindowImpl<*
004592f0HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
004343a0HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00437c90HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
00430440HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>(void)
0041c990HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
0044cf50HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
004539a0HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00435800HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00434640HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
00437440HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::GetWndCaption(void)
00436020HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00453f70HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
00424e30HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
004338a0HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0041c4f0HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00441b50HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
004365f0HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00455120HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
0040ea20HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00453fa0HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
0041abc0HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00459c20HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0045f640HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
004608a0HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndClassInfo(void)
0045fed0HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00433a70HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00437c60HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
0044fb70HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0041acf0HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00459510HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
00437a90HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
00430490HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::~CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>(void)
00424de0HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00433ac0HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00433850HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00433b60HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00452050HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0044f8e0HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0044cec0HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
004340e0HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00433ef0HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
004348c0HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::~CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>(void)
004535b0HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
00454170HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
00459c70HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00451ed0HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00451f20HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0045c4b0HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00436320HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
004536a0HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
004604a0HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::GetWndCaption(void)
0040eca0HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
0045ff90HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
00437cc0HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
004366e0HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
0045e620HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
004608d0HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndCaption(void)
004520a0HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
0045d210HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>(void)
004d84a8HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d84b8HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d7970HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d7960HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d914cHYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8dd0HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8b04HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d8b14HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8ae8HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e31b8HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004e2980HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d88c4HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8330HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d88f0HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d88e0HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d8a40HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e30f0HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d8a5cHYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d8a6cHYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004e21d0HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d8c70HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e2e78HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004e1f00HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>`RTTITypeDescriptor"=<notypeinformation>
004d9208HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d9218HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004e1ad8HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d834cHYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d835cHYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8c9cHYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8c8cHYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d856cHYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d855cHYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004e2bb8HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d7fa0HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d7fb0HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d91ecHYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e2048HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d8174HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d8184HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::`RTTIBaseClassArray"=<notypeinformation>
004d8dfcHYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8decHYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004e2728HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004e28c8HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d8facHYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8f9cHYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d848cHYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8f80HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8158HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8540HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d7944HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d7f84HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e2aa0HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d9168HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d9178HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004e1628HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004e2148HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d95c4HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::`RTTIBaseClassArray"=<notypeinformation>
004d95b4HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004e3400HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>`RTTITypeDescriptor"=<notypeinformation>
004d9598HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>

上面的符号可以验证我们多份实例的猜想。
可以看到CWindowImpl和我们的窗口继承类(T),窗口基类(TBase),窗口风格(TWinTraits)相关,所以数量很多。 那么为什么这么多的符号,也就是这么多的函数代码,exe大小没有被撑大?
那时因为CWindowImpl类函数本身很小,我们从函数的代码量上就可以看出来。

用同样的方法,我们可以继续分析CWindowImplBaseT

复制代码代码如下:
template<classTBase=CWindow,classTWinTraits=CControlWinTraits>
classATL_NO_VTABLECWindowImplBaseT:publicCWindowImplRoot<TBase>
{
public:
   WNDPROCm_pfnSuperWindowProc;

   CWindowImplBaseT():m_pfnSuperWindowProc(::DefWindowProc)
   {}

   staticDWORDGetWndStyle(DWORDdwStyle)
   {
       returnTWinTraits::GetWndStyle(dwStyle);
   }
   staticDWORDGetWndExStyle(DWORDdwExStyle)
   {
       returnTWinTraits::GetWndExStyle(dwExStyle);
   }

   virtualWNDPROCGetWindowProc()
   {
       returnWindowProc;
   }
   staticLRESULTCALLBACKStartWindowProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);
   staticLRESULTCALLBACKWindowProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);
   HWNDCreate(HWNDhWndParent,_U_RECTrect,LPCTSTRszWindowName,
           DWORDdwStyle,DWORDdwExStyle,_U_MENUorIDMenuOrID,ATOMatom,LPVOIDlpCreateParam=NULL);
   BOOLDestroyWindow()
   {
       ATLASSERT(::IsWindow(m_hWnd));
       return::DestroyWindow(m_hWnd);
   }
   BOOLSubclassWindow(HWNDhWnd);
   HWNDUnsubclassWindow(BOOLbForce=FALSE);

   LRESULTDefWindowProc()
   {
       const_ATL_MSG*pMsg=m_pCurrentMsg;
       LRESULTlRes=0;
       if(pMsg!=NULL)
           lRes=DefWindowProc(pMsg->message,pMsg->wParam,pMsg->lParam);
       returnlRes;
   }

   LRESULTDefWindowProc(UINTuMsg,WPARAMwParam,LPARAMlParam)
   {
#ifdefSTRICT
       return::CallWindowProc(m_pfnSuperWindowProc,m_hWnd,uMsg,wParam,lParam);
#else
       return::CallWindowProc((FARPROC)m_pfnSuperWindowProc,m_hWnd,uMsg,wParam,lParam);
#endif
   }

   virtualvoidOnFinalMessage(HWND/*hWnd*/)
   {
       //overridetodosomething,ifneeded
   }
};


复制代码代码如下:
0:000>xHYTeris!ATL::CWindowImplBaseT<*
0040f170HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,unsignedshort,void*)
0040ec20HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndStyle(unsignedlong)
00435970HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::OnFinalMessage(structHWND__*)
004604d0HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::GetWndStyle(unsignedlong)
00434a10HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::~CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
0040ec60HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWndExStyle(unsignedlong)
00461740HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::WindowProc(structHWND__*,unsignedint,unsignedint,long)
0044c040HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::WindowProc(structHWND__*,unsignedint,unsignedint,long)
004346e0HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::~CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
0041c440HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00435940HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::GetWindowProc(void)
00459580HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::GetWndExStyle(unsignedlong)
00461950HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,unsignedshort,void*)
004395b0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::StartWindowProc(structHWND__*,unsignedint,unsignedint,long)
00439ea0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::DefWindowProcW(unsignedint,unsignedint,long)
00461620HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::StartWindowProc(structHWND__*,unsignedint,unsignedint,long)
004596e0HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,unsignedshort,void*)
0041ced0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::WindowProc(structHWND__*,unsignedint,unsignedint,long)
0044c370HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::UnsubclassWindow(int)
00460510HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::GetWndExStyle(unsignedlong)
00457f70HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::WindowProc(structHWND__*,unsignedint,unsignedint,long)
0045f830HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::GetWindowProc(void)
00457820HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
004374b0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::GetWndExStyle(unsignedlong)
00434ad0HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::~CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>(void)
004595c0HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::StartWindowProc(structHWND__*,unsignedint,unsignedint,long)
004358f0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>(void)
00445920HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::OnFinalMessage(structHWND__*)
00461ad0HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::DefWindowProcW(unsignedint,unsignedint,long)
0041c4c0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::OnFinalMessage(structHWND__*)
00437470HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::GetWndStyle(unsignedlong)
004398e0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::Create(structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,unsignedshort,void*)
0040ed50HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::StartWindowProc(structHWND__*,unsignedint,unsignedint,long)
004458a0HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>(void)
0045f7e0HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>(void)
0041ad30HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::~CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>(void)
00430550HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::~CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>(void)
0045f860HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::OnFinalMessage(structHWND__*)
004582a0HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::UnsubclassWindow(int)
0041c490HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::GetWindowProc(void)
0044cb50HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::DefWindowProcW(unsignedint,unsignedint,long)
0044c250HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::SubclassWindow(structHWND__*)
004458f0HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::GetWindowProc(void)
00459540HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::GetWndStyle(unsignedlong)
00458180HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::SubclassWindow(structHWND__*)
00457870HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::GetWindowProc(void)
00457910HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::OnFinalMessage(structHWND__*)
0040e990HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::DestroyWindow(void)
004396d0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::WindowProc(structHWND__*,unsignedint,unsignedint,long)
0041d1c0HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::DefWindowProcW(unsignedint,unsignedint,long)
004578a0HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::DefWindowProcW(unsignedint,unsignedint,long)
004d8fc8HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8ff4HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8fe4HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d79b4HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d79a4HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004e2798HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d819cHYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d8938HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassArray"=<notypeinformation>
004d8928HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d960cHYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::`RTTIBaseClassArray"=<notypeinformation>
004d95fcHYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004e2ee8HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d81c8HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::`RTTIBaseClassArray"=<notypeinformation>
004d81b8HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004e34a0HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>`RTTITypeDescriptor"=<notypeinformation>
004d95e0HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0>>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e1f68HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400>>`RTTITypeDescriptor"=<notypeinformation>
004e1688HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>`RTTITypeDescriptor"=<notypeinformation>
004d7988HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d890cHYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>

可以看到CWindowImplBaseT只与窗口基类和窗口风格相关,数量已经减小很多,CWindowImplBaseT模板类本身函数数量不多,函数代码量大小也不大。

然后再看CWindowImplRoot,

复制代码代码如下:
template<classTBase/*=CWindow*/>
classATL_NO_VTABLECWindowImplRoot:publicTBase,publicCMessageMap
{
public:
   CWndProcThunkm_thunk;
   const_ATL_MSG*m_pCurrentMsg;
   DWORDm_dwState;

   enum{WINSTATE_DESTROYED=0x00000001};

//Constructor/destructor
   CWindowImplRoot():m_pCurrentMsg(NULL),m_dwState(0)
   {}

   virtual~CWindowImplRoot()
   {
#ifdef_DEBUG
       if(m_hWnd!=NULL)   //shouldbeclearedinWindowProc
       {
           ATLTRACE(atlTraceWindowing,0,_T("ERROR-Objectdeletedbeforewindowwasdestroyed\n"));
           ATLASSERT(FALSE);
       }
#endif//_DEBUG
   }

//Currentmessage
   const_ATL_MSG*GetCurrentMessage()const
   {
       returnm_pCurrentMsg;
   }

   //"handled"managementforcrackedhandlers
   BOOLIsMsgHandled()const
   {
       const_ATL_MSG*pMsg=GetCurrentMessage();
       ATLASSERT(pMsg!=NULL);
       ATLASSERT(pMsg->cbSize>=sizeof(_ATL_MSG));
       returnpMsg->bHandled;
   }
   voidSetMsgHandled(BOOLbHandled)
   {
       _ATL_MSG*pMsg=(_ATL_MSG*)GetCurrentMessage();   //overrideconst
       ATLASSERT(pMsg!=NULL);
       ATLASSERT(pMsg->cbSize>=sizeof(_ATL_MSG));
       pMsg->bHandled=bHandled;
   }

//Messageforwardingandreflectionsupport
   LRESULTForwardNotifications(UINTuMsg,WPARAMwParam,LPARAMlParam,BOOL&bHandled);
   LRESULTReflectNotifications(UINTuMsg,WPARAMwParam,LPARAMlParam,BOOL&bHandled);
   staticBOOLDefaultReflectionHandler(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam,LRESULT&lResult);
};


复制代码代码如下:
0:000>xHYTeris!ATL::CWindowImplRoot*
004364d0HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>::~CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>(void)
004367d0HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>::~CWindowImplRoot<WTL::CEditT<ATL::CWindow>>(void)
00457c30HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>(void)
00460550HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>(void)
004479d0HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>(void)
0041c360HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::~CWindowImplRoot<ATL::CWindow>(void)
00435f40HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>::~CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>(void)
004613f0HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::ForwardNotifications(unsignedint,unsignedint,long,int*)
00438f50HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::ReflectNotifications(unsignedint,unsignedint,long,int*)
0041c8e0HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::CWindowImplRoot<ATL::CWindow>(void)
004e2800HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>`RTTITypeDescriptor"=<notypeinformation>
004d897cHYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>::`RTTIBaseClassArray"=<notypeinformation>
004d896cHYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d9640HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d9650HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>::`RTTIBaseClassArray"=<notypeinformation>
004d8950HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d9028HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d9038HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>::`RTTIBaseClassArray"=<notypeinformation>
004e16dcHYTeris!ATL::CWindowImplRoot<ATL::CWindow>`RTTITypeDescriptor"=<notypeinformation>
004e3530HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>`RTTITypeDescriptor"=<notypeinformation>
004d9624HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d79c8HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004e2f58HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>`RTTITypeDescriptor"=<notypeinformation>
004d79f4HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::`RTTIBaseClassArray"=<notypeinformation>
004d79e4HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d900cHYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow>>::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>

可以看到CWindowImplRoot只和窗口基类(CWindow)相关,所以相关的符号就更少了。

最后我们再看一下CWindow:

复制代码代码如下:
0:000>xHYTeris!ATL::CWindow::*
004e1000HYTeris!ATL::CWindow::rcDefault=structtagRECT
00442a20HYTeris!ATL::CWindow::DestroyWindow(void)
00425730HYTeris!ATL::CWindow::InvalidateRect(structtagRECT*,int)
00442340HYTeris!ATL::CWindow::CenterWindow(structHWND__*)
00425850HYTeris!ATL::CWindow::UpdateWindow(void)
0041c950HYTeris!ATL::CWindow::CWindow(structHWND__*)
004391e0HYTeris!ATL::CWindow::GetDlgItem(int)
004568a0HYTeris!ATL::CWindow::SetWindowRgn(structHRGN__*,int)
00441d20HYTeris!ATL::CWindow::GetWindowLongW(int)
00444350HYTeris!ATL::CWindow::Create(wchar_t*,structHWND__*,classATL::_U_RECT,wchar_t*,unsignedlong,unsignedlong,classATL::_U_MENUorID,void*)
004391b0HYTeris!ATL::CWindow::operatorHWND__*(void)
00459080HYTeris!ATL::CWindow::EnableWindow(int)
00425140HYTeris!ATL::CWindow::GetClientRect(structtagRECT*)
00430c70HYTeris!ATL::CWindow::SetWindowTextW(wchar_t*)
0040eb30HYTeris!ATL::CWindow::GetWndClassName(void)
00456770HYTeris!ATL::CWindow::MoveWindow(int,int,int,int,int)
00442ac0HYTeris!ATL::CWindow::KillTimer(unsignedint)
00455fc0HYTeris!ATL::CWindow::GetWindowTextW(wchar_t*,int)
0040ba20HYTeris!ATL::CWindow::IsWindow(void)
00441db0HYTeris!ATL::CWindow::GetParent(void)
004315b0HYTeris!ATL::CWindow::SetWindowPos(structHWND__*,int,int,int,int,unsignedint)
00456810HYTeris!ATL::CWindow::GetWindowRect(structtagRECT*)
00431860HYTeris!ATL::CWindow::GetStyle(void)
00455250HYTeris!ATL::CWindow::Invalidate(int)
004318f0HYTeris!ATL::CWindow::SetCapture(void)
00442cf0HYTeris!ATL::CWindow::SetTimer(unsignedint,unsignedint,<function>*)
00431980HYTeris!ATL::CWindow::ModifyStyle(unsignedlong,unsignedlong,unsignedint)
00443d10HYTeris!ATL::CWindow::GetDlgItemTextW(int,wchar_t*,int)
0040b980HYTeris!ATL::CWindow::SendMessageW(unsignedint,unsignedint,long)
00434be0HYTeris!ATL::CWindow::ShowWindow(int)
004d7a38HYTeris!ATL::CWindow::`RTTIBaseClassDescriptorat(0,-1,0,64)"=<notypeinformation>
004d7a04HYTeris!ATL::CWindow::`RTTIBaseClassDescriptorat(4,-1,0,64)"=<notypeinformation>
004d7a20HYTeris!ATL::CWindow::`RTTIClassHierarchyDescriptor"=<notypeinformation>
004d7a30HYTeris!ATL::CWindow::`RTTIBaseClassArray"=<notypeinformation>

我们看到CWindow只有一份,并且函数数量相比AtlWin.h减少了很多,因为ATL是以源代码的方式提供的,所有没有用到的函数不会被编译到我们最终的可执行文件中。

通过上面的分析,相信我们知道了为什么ATL/WTL大量使用模板,但是生成的exe还是这么小的原因:
不是模板不会使代码膨胀,而是ATL/WTL在设计时就关注了这个问题,它避免了在可能生成很多模板实例的模板类中编写大量代码(有些拗口,不知道你有没有读懂^_^)

总结下,如果你想用模板,但是又不想让自己最终的可执行文件变的很大,
有2种方式:
(1)你的模板类不会生成很多模板实例,这样写成模板类还有意义吗?
(2)你的模板类的代码量或是函数个数很少,你可以仿照ATL的方式把模板无关的东西用继承的方式逐层剥离,确保模板类的代码都是和模板参数相关的。