为什么* everything *在ATL / WTL中使用模板基类?

时间:2012-04-23 02:36:21

标签: c++ winapi visual-c++ atl wtl

我在理解ATL / WTL代码中模板的用途方面遇到了很多麻烦。

当您查看WTL时,您会看到如下代码:

template <class TBase>
class CEditT : public TBase
{
    ...
};

typedef CEditT<ATL::CWindow> CEdit;

为什么用模板基类定义CEditT

换句话说,在CEditT<T> T的情况下,CWindow会在什么情况下实例化?

4 个答案:

答案 0 :(得分:3)

这样你就可以覆盖ATL / WTL类调用的ATL::CWindow中的方法。如果ATL::CWindow中有一些您不喜欢的内容,则可以使用重写方法从ATL::CWindow派生一个类,然后将新类作为TBase传递。

例如,ATL::CWindow::CenterWindow很长一段时间有一个错误,它没有正确地考虑多个监视器,我看到人们使用这种技术来覆盖CenterWindow的固定实现。< / p>

答案 1 :(得分:2)

假设使用了组合物:

template <class TBase> class CEditT {
public:
  TBase base;
  ...
};

这与以下内容没有什么不同:

template <class ITEM> class ListNode {
public:
   ITEM item;
   ListNode<ITEM> *next;
   // ...
};

ListNode可以继承ITEM,就像CEditTTBase一样,但缺点是ITEM不能像int那样基本类型ListNode。另一方面,ITEM然后 一种protected:,这可能很有用。此外,它可以访问ITEM的任何{{1}}部分。

答案 2 :(得分:1)

它可以利用Curiously Recurring Template Pattern。如果您创建CEditT的派生类,则您的定义将为class CMyEdit : public CEditT<CMyEdit>。通过静态地将this指针强制转换为您的班级,CEditT可以调用您的方法,而无需使用vtable。

答案 3 :(得分:0)

  

为什么一切在ATL / WTL中使用模板基类?

简而言之,要获得“奇怪的编译时多态形式” ,这要归功于一种设计模式(而不是C ++惯用语),人们可以将其称为“颠倒继承”。 >作为“指定基类的基类” 的技术,以“允许您将自己的类插入类层次结构” ,以实现专门化类型的灵活性“无需对任何特定的派生类进行硬编码实现”

在阅读了ATL and Upside-Down Inheritance - Understanding ATL's atypical design approach撰写并由Visual C ++ Developers Journal于1999年7月发表的出色文章Jim Beveridge之后,一切都应该变得清楚。这里是link to full not paginated copy of the same article(也在Wayback Machine中)。