WTL for MFC Programmers(3)

原创 2004年04月07日 22:12:00

ATL-style templates<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Even if you can read C++ templates without getting a headache, there is two things ATL does that might trip you up at first. Take this class for example:

关于C++的模版定义,ATL有两个让人头疼的事情。注意以下的例子:

class CMyWnd : public CWindowImpl<CMyWnd>

{

...

};

That actually is legal, because the C++ spec says that immediately after the class CMyWnd part, the name CMyWnd is defined and can be used in the inheritance list. The reason for having the class name as a template parameter is so ATL can do the second tricky thing, compile-time virtual function calls.

上面的代码是合法,因为C++规定只要在class CMyWnd定义部分的后面,就可以使用CMyWnd,当然也可以将它用在基类表的定义中。这就是为什么类名可以像一个模板参数那样使用,也正是由于这样的特性,ATL就有了第二件狡猾的设计,编译时虚函数调用。

(如果在class CMyWnd的后面马上就可以使用CMyWnd,那么能不能让一个类作自己的子类呢?好像可以,其实是行不通的,因为编译器会去找基类的定义,如果自己做自己的基类,编译器会提示基类没有定义 蜗牛手记)

To see this in action, look at this set of classes:

注意看下面的类定义:

template <class T>

class B1

{

public:

    void SayHi()

    {

    T* pT = static_cast<T*>(this);   // HUH?? I'll explain this below

 

        pT->PrintClassName();

    }

protected:

    void PrintClassName() { cout << "This is B1"; }

};

 

class D1 : public B1<D1>

{

    // No overridden functions at all

};

 

class D2 : public B1<D2>

{

protected:

    void PrintClassName() { cout << "This is D2"; }

};

 

main()

{

D1 d1;

D2 d2;

 

    d1.SayHi();    // prints "This is B1"

    d2.SayHi();    // prints "This is D2"

}

The static_cast<T*>(this) is the trick here. It casts this, which is of type B1*, to either D1* or D2* depending on which specialization is being invoked. Because template code is generated at compile-time, this cast is guaranteed to be safe, as long as the inheritance list is written correctly. (If you wrote

class D3 : public B1<D2>

you'd be in trouble.) It's safe because the this object can only be of type D1* or D2* (as appropriate), and nothing else. Notice that this is almost exactly like normal C++ polymorphism, except that the SayHi() method isn't virtual.

语句static_cast<T*>(this)是一个骗局。它通过这个特殊的调用将类型是B1*this转换为D1*或者D2*。因为模板的代码是在编译时生成的,只要基类烈表示正确的,这种转换保证是安全的。(如果你写出这样的语句:class D3 : public B1<D2>,那你将于遇到麻烦)。这种安全是因为this对象只能根据定义转换为D1*D2*,而不能转换为其他的什么东西。这就像标准C++的多态性一样的,只是SayHi()函数不是虚函数而已。

WTL for MFC Programmers(3)

  • zgqtxwd
  • zgqtxwd
  • 2008年04月27日 20:14
  • 153

WTL for MFC Programmers(1)

WTL for MFC Programmers从MFC到WTL 原著 Michael Dunn 编译 蜗牛手记译前序       一直以来都是在MFC的平台上开发,忽然有一天开发的东西需要跨入没有MF...
  • snaill
  • snaill
  • 2004年04月07日 22:17
  • 2382

WTL for MFC Programmers(2)

  • zgqtxwd
  • zgqtxwd
  • 2008年04月27日 20:13
  • 135

WTL for MFC Programmers(5)

Defining a Window Implementation定义一个窗体实现Any non-dialog window you create will derive from CWindowImp...
  • snaill
  • snaill
  • 2004年04月07日 22:12
  • 1129

WTL for MFC Programmers(4)

To explain how this works, lets look at each call to SayHi(). In the first call, the specialization ...
  • snaill
  • snaill
  • 2004年04月07日 22:12
  • 1141

WTL学习笔记——(7)WTL与MFC相比优劣势

WTL 具有两面性,确实是这样的。它没有MFC的界面(GUI)类库那样功能强大,但是能够生成很小的可执行文件。如果你象我一样使用MFC进行界面编程,你会觉得MFC提供的界面控件封装使用起来非常舒服,更...
  • wangningyu
  • wangningyu
  • 2009年11月07日 08:05
  • 4402

WTL for MFC Programmers, 中文版序言

  • zgqtxwd
  • zgqtxwd
  • 2008年04月27日 20:09
  • 127

探索WTL和MFC混合使用的问题,兼容VC2010编译器

     MFC和WTL写界面都有优缺点.MFC编程快速,WTL灵活.目前工作是为了实现即时通信的UI,但是一些特效用MFC实现是相当困难的,例如对话框针对控件的分隔条.但是WTL则处理的相当好,但是...
  • wangji163163
  • wangji163163
  • 2011年05月07日 18:30
  • 2775

MFC程序员的WTL指南系列 (WTL for MFC Programmers Series)

这系列文章介绍了WTL界面开发的一些基础知识,写得浅显易懂,推荐。 源文地址:http://www.codeproject.com/KB/wtl/wtl4mfc1.aspx 中文版本:...
  • HarbinZJU
  • HarbinZJU
  • 2012年01月02日 19:34
  • 822

MFC程序员的WTL指南之WTL 界面基类

现在正式开始介绍WTL!在这一部分我讲的内容包括生成一个基本的主窗口和WTL提供的一些友好的改进,比如UI界面的更新(如菜单上的选择标记)和更好的消息映射机制。为了更好地掌握本章的内容,你应该安装WT...
  • jznsmail
  • jznsmail
  • 2005年02月18日 19:07
  • 2624
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WTL for MFC Programmers(3)
举报原因:
原因补充:

(最多只允许输入30个字)