为WTL设计一个“文档视图”模型.docVIP

  1. 1、本文档共23页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
为WTL设计一个“文档视图”模型

为WTL设计一个“文档-视图”模型 作者:戴霖 bill.dai@163.com前言 2 1- 编译期虚函数调用 嵌入类 3 2- 文档类 4 3- 视图类 5 4- 文档模板类 6 5- 文档模板管理器类 6 6- 上下文信息——CCreateContext 6 7- 改造你的代码 7 8- 模型的工作流程 10 9- 实现代码 11 10- 后记 22 前言 WTL(Windows Template Library,Windows模板库)提供了比MFC库更加精减的代码框架,这其中就省略了对MFC“文档-视图”模型的支持。而“文档-视图”模型的核心思想——将数据和其表示分开,在开发大型软件时颇为有用。那如何既能保留WTL精减方便的优点,又能拥有MFC“文档-视图”模型的精髓呢?本文将探讨一种方法,在为WTL引入“文档-视图”模型的同时,让其接口尽可能地接近于MFC,从而方便实际应用。 我们将构建四个主要的类来实现“文档-视图”模型的行为,分别是文档类、视图类、文档模板类和文档模板管理器类。四部分的关系如下图: 由于WTL是构建在ATL基础之上的,所以其代码风格迥异于MFC,包含了大量的C++模板类代码。即使你能毫不费力地读懂它们,但是下面的仍然可能让你一头雾水: Class CMyWin : public CWindowImplCMyWin { …… }; 这样做是合法的,类名CMyWin已经被列入递归继承列表,是可以使用的。可是为什么要这样做呢?目的何在?这里蕴含了两个概念,一是编译期间的虚函数调用机制,二是嵌入类。1- 编译期虚函数调用 嵌入类 如果你想了解它们如何工作,请看下面的例子;如果你已经有了很好的ATL基础,那么可以直接跳过本章。 例子: template class T class Base {protected: void SayHello() { cout Hello Base; } public: void Print() { T* ptr = static_castT*(this); // 这里我们称之为编译期虚函数调用 ptr-SayHello(); } }; class Deriver1 : public BaseDeriver1 {/*空类*/}; class Deriver2 : public BaseDeriver2 { protected: void SayHello() { cout Hello Deriver2; } }; main() { Deriver1 d1; Deriver2 d2; d1.Print(); // 显示Hello Base d2.Print(); // 显示Hello Deriver2 } 这句代码static_castT*(this) 就是窍门所在。它函数调用时将指向Base类型的指针this为Deriver1或D的指针因为模板代码是在编译期间生成的,所以只要编译器生成正确的继承列表,这就是安全的。因为在这this只能是指向D 1或D 2类型的对象,不会是其他的东西。这很像C++的多态性,只是Print()方法不是虚函数。 要解释这是如何工作的,首先看对每个Print()函数的调用,,对象Base被指派为Deriver1,所以代码被解释成: void BaseDeriver1::Print() { Deriver1* ptr = static_castDeriver1*(this); ptr-SayHello(); } 由于Deriver1没有重载SayHello(),所以查看基类Base,Base有SayHello(),所以Base的SayHello()被调用。 再看,这一次对象被指派为Deriver2类型,Print()被解释成: void BaseDeriver2::Print() { Deriver2* ptr = static_castDeriver2*(this); ptr-SayHello(); } 这一次,Deriver2含有SayHello()方法,所以Deriver2的SayHello()方法被调用。 这种技术的在于: 不需要使用指向对象的指针。 不需要虚函数表节省内存。 因为没有虚函数表所以运行时不发生调用空指针指向的虚函数。 所有的函数调用在编译时确定,而非C++虚函数机制使用的动态联编,这有利于编译程序对代码的优化。 读到这里你应该可以明白什么是编译期间的虚函数调用机制,那么嵌入类又是什么呢?其实这是ATL引入的一个概念,或者叫作“另一种继承机制”更合

文档评论(0)

ipad0a + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档