`
阿尔萨斯
  • 浏览: 4174033 次
社区版块
存档分类
最新评论

ATL界面类——兼谈多态与泛型

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
由于业余时间相对比较少,并且接下来要出差(大约十天左右),看样子winxcn.com短期内不能出来。为了WINX的文档不至于遥遥无期,我决定还是现在开始在blog上连载WINX的核心文档。或许对于这些文档而言,blog不是一个很好的载体,因为blog更关注的是社会性,强调的是参与,而体系性较差。

这是开篇第一篇。你可能觉得惊奇——不是要讲WINX吗?怎么,讲ATL来着?勿须奇怪,WINX是基于ATL/WTL的,所以,在讲WINX的原理之前,先要了解ATL的基本概念,它们一定程度上是相通的。

ATL/WTL的界面开发,网上的教程还是少了点。相信大家都知道《MFC程序员的WTL开发指南》,这的确是一套难得的好教材。作为WINX的入门篇,我们这一篇是回顾《MFC程序员的WTL开发指南》第一篇:“ATL界面类”(注:为了不至于重复制造轮子,我这里不再赘述该文章已经叙述较为详细的一些技术细节)。

接触ATL/WTL久了,类似下面这样的代码你一定见得多了:

class MyClass : BaseClassT<myclass><br>{<br>};<br><br>把派生类MyClass,作为模版参数传递给基类BaseClassT,这种写法多多少少显得有点古怪。但这是合法的。之所以要这样,是因为我们要实现“<strong>编译期</strong>的晚绑定”(<a href="http://dev.yesky.com/SoftChannel/72342371928702976/20050117/1901786.shtml"><font color="#006aba">ATL界面类</font></a>中把它称为“编译期间的虚函数调用机制”,这是不太准确的说法)。<br><br>基于虚函数技术的“<strong>运行期(Runtime)</strong>的晚绑定”大家都已经很熟悉了,这也就是OOP中所谓的“多态”。而基于模板技术,所依赖的并非vtable,而是类型不确定型(类型晚绑定),来达到“编译期的晚绑定”。这也就是所谓的“泛型”。<br><br><strong>选择“多态(虚函数技术)”,还是选择“泛型(模板技术)”?</strong><br><br>模板的好处是“零开销”——即额外的时间、空间开销均为零。而虚函数技术在时间上多了一次间接调用(由vptr找到vtable中相应的函数地址),并导致inline失效(无法展开);在空间上每个类对象多了4字节(这里假设是32bit系统)的vptr,全局多了一个vtable(大小与该类的虚函数个数有关)。<br><br>虚函数的好处是“可定义二进制规范”,从而建立语言无关的调用约定。这就是COM(组件对象模型)技术关注的内容。进一步来说,虚函数技术比较适合应用于大型程序中的模块划分,用以描述组件间调用契约——interface(接口)。<br><br>我并不是模板技术的推崇者。应当认识到,模板与虚函数技术一样,只适合有限的场合。WINX中,消息分派机制使用了模板,是因为它是最适合的人选。<br><br>作为结束,我提醒读者,理解泛型中的“编译期的晚绑定”是重要的,如果你希望深入理解WINX的话。下一节我们开始进入最关键的章节——WINX的消息机制。</myclass>

由于我发不了评论,故此回复sting在此:

很高兴你提出这个问题。看来你对C++了解很深。我也很不满意,C++没有二进制规范。

其实你说得没错,从理论上来说虚表没有二进制规范,这种标准是工业上的标准。gcc大概在3.0版本(记不太清楚了)以前,其虚表就不符合COM规范,后来迫于无奈修改了。这对gcc影响甚深,因为这意味着gcc3.0以前版本编译出来的so/dll不能与高版本的gcc编译的so/dll之间相互进行调用。




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics