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

今天和同事说到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 <class T, class TBase /* = CWindow */, class TWinTraits /* = CControlWinTraits */>
class ATL_NO_VTABLE CWindowImpl : public CWindowImplBaseT< TBase, TWinTraits >
{
public:
    DECLARE_WND_CLASS(NULL)

    static LPCTSTR GetWndCaption()
    {
        return NULL;
    }

    HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
            DWORD dwStyle = 0, DWORD dwExStyle = 0,
            _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
    {
        if (T::GetWndClassInfo().m_lpszOrigName == NULL)
            T::GetWndClassInfo().m_lpszOrigName = GetWndClassName();
        ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);

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

        // set caption
        if (szWindowName == NULL)
            szWindowName = T::GetWndCaption();

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

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

复制代码 代码如下:

0:000> x HYTeris!ATL::CWindowImpl<*
004592f0 HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
004343a0 HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00437c90 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
00430440 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> > (void)
0041c990 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
0044cf50 HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
004539a0 HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00435800 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00434640 HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
00437440 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::GetWndCaption (void)
00436020 HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00453f70 HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
00424e30 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
004338a0 HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0041c4f0 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00441b50 HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
004365f0 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00455120 HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
0040ea20 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00453fa0 HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
0041abc0 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00459c20 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0045f640 HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
004608a0 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndClassInfo (void)
0045fed0 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00433a70 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00437c60 HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
0044fb70 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0041acf0 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00459510 HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
00437a90 HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
00430490 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::~CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> > (void)
00424de0 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00433ac0 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00433850 HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00433b60 HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00452050 HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0044f8e0 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0044cec0 HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
004340e0 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00433ef0 HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
004348c0 HYTeris!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)
004535b0 HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
00454170 HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
00459c70 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00451ed0 HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00451f20 HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0045c4b0 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00436320 HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
004536a0 HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
004604a0 HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::GetWndCaption (void)
0040eca0 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
0045ff90 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
00437cc0 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
004366e0 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
0045e620 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
004608d0 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndCaption (void)
004520a0 HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
0045d210 HYTeris!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)
004d84a8 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d84b8 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d7970 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d7960 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d914c HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8dd0 HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8b04 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d8b14 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8ae8 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e31b8 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004e2980 HYTeris!ATL::CWindowImpl<CTsMainDisplayPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d88c4 HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8330 HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d88f0 HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d88e0 HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d8a40 HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e30f0 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d8a5c HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d8a6c HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004e21d0 HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d8c70 HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e2e78 HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004e1f00 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> > `RTTI Type Descriptor' = <no type information>
004d9208 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d9218 HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004e1ad8 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d834c HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d835c HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8c9c HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8c8c HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d856c HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d855c HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004e2bb8 HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d7fa0 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d7fb0 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d91ec HYTeris!ATL::CWindowImpl<CTsSingleControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e2048 HYTeris!ATL::CWindowImpl<CTsMainButtonPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d8174 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d8184 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::`RTTI Base Class Array' = <no type information>
004d8dfc HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8dec HYTeris!ATL::CWindowImpl<CTsMutiScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004e2728 HYTeris!ATL::CWindowImpl<CTsKeyEdit,WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004e28c8 HYTeris!ATL::CWindowImpl<CTsNextElementContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d8fac HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8f9c HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d848c HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8f80 HYTeris!ATL::CWindowImpl<CTsButton,WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8158 HYTeris!ATL::CWindowImpl<CTsGameMainWnd,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8540 HYTeris!ATL::CWindowImpl<CTsMainStatusPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d7944 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d7f84 HYTeris!ATL::CWindowImpl<CTsDisplayContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e2aa0 HYTeris!ATL::CWindowImpl<CTsSingleScoreContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d9168 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d9178 HYTeris!ATL::CWindowImpl<CTsSubControlContainer,ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004e1628 HYTeris!ATL::CWindowImpl<CTsAgentWindow,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004e2148 HYTeris!ATL::CWindowImpl<CTsMainControlPane,ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d95c4 HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::`RTTI Base Class Array' = <no type information>
004d95b4 HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::`RTTI Class Hierarchy Descriptor' = <no type information>
004e3400 HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > > `RTTI Type Descriptor' = <no type information>
004d9598 HYTeris!ATL::CWindowImpl<CTsUserListCtrl,WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>

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

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

复制代码 代码如下:

template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE CWindowImplBaseT : public CWindowImplRoot< TBase >
{
public:
    WNDPROC m_pfnSuperWindowProc;

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

    static DWORD GetWndStyle(DWORD dwStyle)
    {
        return TWinTraits::GetWndStyle(dwStyle);
    }
    static DWORD GetWndExStyle(DWORD dwExStyle)
    {
        return TWinTraits::GetWndExStyle(dwExStyle);
    }

    virtual WNDPROC GetWindowProc()
    {
        return WindowProc;
    }
    static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    HWND Create(HWND hWndParent, _U_RECT rect, LPCTSTR szWindowName,
            DWORD dwStyle, DWORD dwExStyle, _U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam = NULL);
    BOOL DestroyWindow()
    {
        ATLASSERT(::IsWindow(m_hWnd));
        return ::DestroyWindow(m_hWnd);
    }
    BOOL SubclassWindow(HWND hWnd);
    HWND UnsubclassWindow(BOOL bForce = FALSE);

    LRESULT DefWindowProc()
    {
        const _ATL_MSG* pMsg = m_pCurrentMsg;
        LRESULT lRes = 0;
        if (pMsg != NULL)
            lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
        return lRes;
    }

    LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
#ifdef STRICT
        return ::CallWindowProc(m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
#else
        return ::CallWindowProc((FARPROC)m_pfnSuperWindowProc, m_hWnd, uMsg, wParam, lParam);
#endif
    }

    virtual void OnFinalMessage(HWND /*hWnd*/)
    {
        // override to do something, if needed
    }
};

复制代码 代码如下:

0:000> x HYTeris!ATL::CWindowImplBaseT<*
0040f170 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, unsigned short, void *)
0040ec20 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndStyle (unsigned long)
00435970 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::OnFinalMessage (struct HWND__ *)
004604d0 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::GetWndStyle (unsigned long)
00434a10 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::~CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
0040ec60 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWndExStyle (unsigned long)
00461740 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::WindowProc (struct HWND__ *, unsigned int, unsigned int, long)
0044c040 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::WindowProc (struct HWND__ *, unsigned int, unsigned int, long)
004346e0 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::~CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
0041c440 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00435940 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::GetWindowProc (void)
00459580 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::GetWndExStyle (unsigned long)
00461950 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, unsigned short, void *)
004395b0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::StartWindowProc (struct HWND__ *, unsigned int, unsigned int, long)
00439ea0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::DefWindowProcW (unsigned int, unsigned int, long)
00461620 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::StartWindowProc (struct HWND__ *, unsigned int, unsigned int, long)
004596e0 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, unsigned short, void *)
0041ced0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::WindowProc (struct HWND__ *, unsigned int, unsigned int, long)
0044c370 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::UnsubclassWindow (int)
00460510 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::GetWndExStyle (unsigned long)
00457f70 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::WindowProc (struct HWND__ *, unsigned int, unsigned int, long)
0045f830 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::GetWindowProc (void)
00457820 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
004374b0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::GetWndExStyle (unsigned long)
00434ad0 HYTeris!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)
004595c0 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::StartWindowProc (struct HWND__ *, unsigned int, unsigned int, long)
004358f0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> > (void)
00445920 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::OnFinalMessage (struct HWND__ *)
00461ad0 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::DefWindowProcW (unsigned int, unsigned int, long)
0041c4c0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::OnFinalMessage (struct HWND__ *)
00437470 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::GetWndStyle (unsigned long)
004398e0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::Create (struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, unsigned short, void *)
0040ed50 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::StartWindowProc (struct HWND__ *, unsigned int, unsigned int, long)
004458a0 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > (void)
0045f7e0 HYTeris!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)
0041ad30 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::~CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> > (void)
00430550 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::~CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> > (void)
0045f860 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::OnFinalMessage (struct HWND__ *)
004582a0 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::UnsubclassWindow (int)
0041c490 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::GetWindowProc (void)
0044cb50 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::DefWindowProcW (unsigned int, unsigned int, long)
0044c250 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::SubclassWindow (struct HWND__ *)
004458f0 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::GetWindowProc (void)
00459540 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::GetWndStyle (unsigned long)
00458180 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::SubclassWindow (struct HWND__ *)
00457870 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::GetWindowProc (void)
00457910 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::OnFinalMessage (struct HWND__ *)
0040e990 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::DestroyWindow (void)
004396d0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::WindowProc (struct HWND__ *, unsigned int, unsigned int, long)
0041d1c0 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::DefWindowProcW (unsigned int, unsigned int, long)
004578a0 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::DefWindowProcW (unsigned int, unsigned int, long)
004d8fc8 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8ff4 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8fe4 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d79b4 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d79a4 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004e2798 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d819c HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d8938 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Array' = <no type information>
004d8928 HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d960c HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::`RTTI Base Class Array' = <no type information>
004d95fc HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::`RTTI Class Hierarchy Descriptor' = <no type information>
004e2ee8 HYTeris!ATL::CWindowImplBaseT<WTL::CButtonT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d81c8 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::`RTTI Base Class Array' = <no type information>
004d81b8 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004e34a0 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > > `RTTI Type Descriptor' = <no type information>
004d95e0 HYTeris!ATL::CWindowImplBaseT<WTL::CListViewCtrlT<ATL::CWindow>,ATL::CWinTraitsOR<32777,0,ATL::CWinTraits<1442840576,0> > >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e1f68 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> > `RTTI Type Descriptor' = <no type information>
004e1688 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> > `RTTI Type Descriptor' = <no type information>
004d7988 HYTeris!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d890c HYTeris!ATL::CWindowImplBaseT<WTL::CEditT<ATL::CWindow>,ATL::CWinTraits<1442840576,0> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>

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

然后再看CWindowImplRoot,

复制代码 代码如下:

template <class TBase /* = CWindow */>
class ATL_NO_VTABLE CWindowImplRoot : public TBase, public CMessageMap
{
public:
    CWndProcThunk m_thunk;
    const _ATL_MSG* m_pCurrentMsg;
    DWORD m_dwState;

    enum { WINSTATE_DESTROYED = 0x00000001 };

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

    virtual ~CWindowImplRoot()
    {
#ifdef _DEBUG
        if(m_hWnd != NULL)    // should be cleared in WindowProc
        {
            ATLTRACE(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));
            ATLASSERT(FALSE);
        }
#endif //_DEBUG
    }

// Current message
    const _ATL_MSG* GetCurrentMessage() const
    {
        return m_pCurrentMsg;
    }

    // "handled" management for cracked handlers
    BOOL IsMsgHandled() const
    {
        const _ATL_MSG* pMsg = GetCurrentMessage();
        ATLASSERT(pMsg != NULL);
        ATLASSERT(pMsg->cbSize >= sizeof(_ATL_MSG));
        return pMsg->bHandled;
    }
    void SetMsgHandled(BOOL bHandled)
    {
        _ATL_MSG* pMsg = (_ATL_MSG*)GetCurrentMessage();    // override const
        ATLASSERT(pMsg != NULL);
        ATLASSERT(pMsg->cbSize >= sizeof(_ATL_MSG));
        pMsg->bHandled = bHandled;
    }

// Message forwarding and reflection support
    LRESULT ForwardNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    LRESULT ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    static BOOL DefaultReflectionHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult);
};

复制代码 代码如下:

0:000> x HYTeris!ATL::CWindowImplRoot*
004364d0 HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> >::~CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> > (void)
004367d0 HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow> >::~CWindowImplRoot<WTL::CEditT<ATL::CWindow> > (void)
00457c30 HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> >::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> > (void)
00460550 HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> >::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> > (void)
004479d0 HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow> >::CWindowImplRoot<WTL::CEditT<ATL::CWindow> > (void)
0041c360 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::~CWindowImplRoot<ATL::CWindow> (void)
00435f40 HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> >::~CWindowImplRoot<WTL::CButtonT<ATL::CWindow> > (void)
004613f0 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::ForwardNotifications (unsigned int, unsigned int, long, int *)
00438f50 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::ReflectNotifications (unsigned int, unsigned int, long, int *)
0041c8e0 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::CWindowImplRoot<ATL::CWindow> (void)
004e2800 HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow> > `RTTI Type Descriptor' = <no type information>
004d897c HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow> >::`RTTI Base Class Array' = <no type information>
004d896c HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d9640 HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d9650 HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> >::`RTTI Base Class Array' = <no type information>
004d8950 HYTeris!ATL::CWindowImplRoot<WTL::CEditT<ATL::CWindow> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d9028 HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> >::`RTTI Class Hierarchy Descriptor' = <no type information>
004d9038 HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> >::`RTTI Base Class Array' = <no type information>
004e16dc HYTeris!ATL::CWindowImplRoot<ATL::CWindow> `RTTI Type Descriptor' = <no type information>
004e3530 HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> > `RTTI Type Descriptor' = <no type information>
004d9624 HYTeris!ATL::CWindowImplRoot<WTL::CListViewCtrlT<ATL::CWindow> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d79c8 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004e2f58 HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> > `RTTI Type Descriptor' = <no type information>
004d79f4 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::`RTTI Base Class Array' = <no type information>
004d79e4 HYTeris!ATL::CWindowImplRoot<ATL::CWindow>::`RTTI Class Hierarchy Descriptor' = <no type information>
004d900c HYTeris!ATL::CWindowImplRoot<WTL::CButtonT<ATL::CWindow> >::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>

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

最后我们再看一下CWindow:

复制代码 代码如下:

0:000> x HYTeris!ATL::CWindow::*
004e1000 HYTeris!ATL::CWindow::rcDefault = struct tagRECT
00442a20 HYTeris!ATL::CWindow::DestroyWindow (void)
00425730 HYTeris!ATL::CWindow::InvalidateRect (struct tagRECT *, int)
00442340 HYTeris!ATL::CWindow::CenterWindow (struct HWND__ *)
00425850 HYTeris!ATL::CWindow::UpdateWindow (void)
0041c950 HYTeris!ATL::CWindow::CWindow (struct HWND__ *)
004391e0 HYTeris!ATL::CWindow::GetDlgItem (int)
004568a0 HYTeris!ATL::CWindow::SetWindowRgn (struct HRGN__ *, int)
00441d20 HYTeris!ATL::CWindow::GetWindowLongW (int)
00444350 HYTeris!ATL::CWindow::Create (wchar_t *, struct HWND__ *, class ATL::_U_RECT, wchar_t *, unsigned long, unsigned long, class ATL::_U_MENUorID, void *)
004391b0 HYTeris!ATL::CWindow::operator HWND__ * (void)
00459080 HYTeris!ATL::CWindow::EnableWindow (int)
00425140 HYTeris!ATL::CWindow::GetClientRect (struct tagRECT *)
00430c70 HYTeris!ATL::CWindow::SetWindowTextW (wchar_t *)
0040eb30 HYTeris!ATL::CWindow::GetWndClassName (void)
00456770 HYTeris!ATL::CWindow::MoveWindow (int, int, int, int, int)
00442ac0 HYTeris!ATL::CWindow::KillTimer (unsigned int)
00455fc0 HYTeris!ATL::CWindow::GetWindowTextW (wchar_t *, int)
0040ba20 HYTeris!ATL::CWindow::IsWindow (void)
00441db0 HYTeris!ATL::CWindow::GetParent (void)
004315b0 HYTeris!ATL::CWindow::SetWindowPos (struct HWND__ *, int, int, int, int, unsigned int)
00456810 HYTeris!ATL::CWindow::GetWindowRect (struct tagRECT *)
00431860 HYTeris!ATL::CWindow::GetStyle (void)
00455250 HYTeris!ATL::CWindow::Invalidate (int)
004318f0 HYTeris!ATL::CWindow::SetCapture (void)
00442cf0 HYTeris!ATL::CWindow::SetTimer (unsigned int, unsigned int, <function> *)
00431980 HYTeris!ATL::CWindow::ModifyStyle (unsigned long, unsigned long, unsigned int)
00443d10 HYTeris!ATL::CWindow::GetDlgItemTextW (int, wchar_t *, int)
0040b980 HYTeris!ATL::CWindow::SendMessageW (unsigned int, unsigned int, long)
00434be0 HYTeris!ATL::CWindow::ShowWindow (int)
004d7a38 HYTeris!ATL::CWindow::`RTTI Base Class Descriptor at (0,-1,0,64)' = <no type information>
004d7a04 HYTeris!ATL::CWindow::`RTTI Base Class Descriptor at (4,-1,0,64)' = <no type information>
004d7a20 HYTeris!ATL::CWindow::`RTTI Class Hierarchy Descriptor' = <no type information>
004d7a30 HYTeris!ATL::CWindow::`RTTI Base Class Array' = <no type information>

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

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

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

时间: 2024-07-28 20:39:56

深入分析:C++模板究竟会使代码膨胀吗_C 语言的相关文章

深入分析C++派生类中的保护成员继承_C 语言

protected 与 public 和 private 一样是用来声明成员的访问权限的.由protected声明的成员称为"受保护的成员",或简称"保护成员".从类的用户角度来看,保护成员等价于私有成员.但有一点与私有成员不同,保护成员可以被派生类的成员函数引用. 如果基类声明了私有成员,那么任何派生类都是不能访问它们的,若希望在派生类中能访问它们,应当把它们声明为保护成员.如果在一个类中声明了保护成员,就意味着该类可能要用作基类,在它的派生类中会访问这些成员.

C++选择文件夹代码的封装_C 语言

本文实例讲述了C++选择文件夹代码的封装,分享给大家供大家参考.具体方法如下: 该实例分为DirDialog.h头文件与DirDialog.cpp源文件. DirDialog.h头文件代码如下: 复制代码 代码如下: #pragma once  #ifndef __DIRDIALOG_H_HH  #define __DIRDIALOG_H_HH  #include <Shlobj.h>   class CDirDialog  {  protected:      BROWSEINFO m_bi

C++加密解密php代码的方法_C 语言

本文实例讲述了C++加密解密php代码的方法.分享给大家供大家参考.具体实现方法如下: #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "string.h" char * key = "abcd"; PHP_FUNCTION(encode){ long key_len = strlen(key); c

C语言中的数组和指针汇编代码分析实例_C 语言

今天看<程序员面试宝典>时偶然看到讲数组和指针的存取效率,闲着无聊,就自己写了段小代码,简单分析一下C语言背后的汇编,可能很多人只注重C语言,但在实际应用当中,当出现问题时,有时候还是通过分析汇编代码能够解决问题.本文只是为初学者,大牛可以飘过~ C源代码如下: 复制代码 代码如下: #include "stdafx.h" int main(int argc, char* argv[]) {        char a=1;        char c[] = "

基于malloc与free函数的实现代码及分析_C 语言

用于内存管理的malloc与free这对函数,对于使用C语言的程序员应该很熟悉.前段时间听说有的IT公司以"实现一个简单功能的malloc"作为面试题,正好最近在复习K&R,上面有所介绍,因此花了些时间仔细研究了一下.毕竟把题目做出来是次要的,了解实现思想.提升技术才是主要的.本文主要是对malloc与free实现思路的介绍,蓝色部分文字是在个人思考中觉得比较核心的东西:另外对于代码的说明,有一些K&R上的解释,使用绿色加亮. 在研究K&R第八章第五节的实现之前

大数据情况下桶排序算法的运用与C++代码实现示例_C 语言

箱排序的变种.为了区别于上述的箱排序,姑且称它为桶排序(实际上箱排序和桶排序是同义词). 桶排序的思想是把[0,1)划分为n个大小相同的子区间,每一子区间是一个桶.然后将n个记录分配到各个桶中.因为关键字序列是均匀分布在[0,1)上的,所以一般不会有很多个记录落入同一个桶中.由于同一桶中的记录其关键字不尽相同,所以必须采用关键字比较的排序方法(通常用插入排序)对各个桶进行排序,然后依次将各非空桶中的记录连接(收集)起来即可. 注意: 这种排序思想基于以下假设:假设输入的n个关键字序列是随机分布在

详解Bucket Sort桶排序算法及C++代码实现示例_C 语言

桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里.每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序).桶排序是鸽巢排序的一种归纳结果.当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n)).但桶排序并不是比较排序,他不受到O(n log n)下限的影响. 桶排序以下列程序进行: 1.设置一个定量的数组当作空桶子. 2.寻访序列,并且把项目一个一个放到对应的桶子去. 3.对每个不是空的桶子进行排

重构-使代码更简洁优美:实际经验之谈(提供一技巧,让你省掉N多代码)

这几天没怎么写文,因为在用 CYQ.Data  框架 重构以前的一个博客源码,而在重构的过程中,最关键的就是简化代码了.   今天,我将说一个很典型的示例,看完本示例后,不要惊讶,不要怀疑,它不是神马,也不是浮云,   而是很实在的一种方式,能让你节省了N多的代码,让你的代码看起来更简洁优美.   而这里说的一个很典型的示例,是从我目前重构中的博客中应用而来的:   一:正常的开发方式   1:扫一眼当前的项目解决方案   2:说说Module库 一般我们很常见的会有一个页面基类,当然各花叫法不

城市联动-求淘宝运费模板的城市设置代码

问题描述 求淘宝运费模板的城市设置代码 可惜不让上传图片 不知道有没有见过那样的效果. 如: 华东 上海 江苏 浙江 安徽 江西 每个前面都有个复选框,除开 华东 以外各个省后面有个倒三角图标,点击就弹出另外一个图层,显示省下面的各个城市.各个城市前面也有复选框. 效果: 1.点击省前面的复选框,默认就把倒三角里面的所有城市选中了 2.也可以不选择省,只单独选择倒三角里面的部分城市. 3.选中华东,对应的省又全部被选中. 4.保存后,显示,如果选择的是省就显示省,如果选择的是市就显示市.