网站大量收购独家精品文档,联系QQ:2885784924

理解虚基类、虚函数及纯虚函数的概念.doc

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
理解虚基类、虚函数与纯虚函数的概念 引言 ???? 一直以来都没有写过一篇关于概念性的文章,因为我觉得这些概念性的东西书本上都有并且说的也很详细写来也无用,今天突发奇想想写 一写,下面就和大家讨论一下虚基类、虚函数与纯虚函数,一看名字就让人很容易觉得混乱。不过不要紧待看完本文后你就会理解了。 正文 ? ?? ? 虚基类 ? ?? ? 在说明其作用前先看一段代码 class?A { public: ????int?iValue; }; class?B:public?A { public: ????void?bPrintf(){coutThis?is?class?Bendl;}; }; class?C:public?A { public: ????void?cPrintf(){coutThis?is?class?Cendl;}; }; class?D:public?B,public?C { public: ????void?dPrintf(){coutThis?is?class?Dendl;}; }; void?main() { ????D?d; ????coutd.iValueendl;?//错误,不明确的访问 ????coutd.A::iValueendl;?//正确 ????coutd.B::iValueendl;?//正确 ????coutd.C::iValueendl;?//正确 } 从代码中可以看出类B C都继承了类A的iValue成员,因此类B C都有一个成员变量iValue ,而类D又继承了B C,这样类D就有一个重名的成员 iValue(一个是从类B中继承过来的,一个是从类C中继承过来的).在主函数中调用d.iValue 因为类D有一个重名的成员iValue编译器不知道调用 从谁继承过来的iValue所以就产生的二义性的问题.正确的做法应该是加上作用域限定符 d.B::iValue 表示调用从B类继承过来的iValue。不过 类D的实例中就有多个iValue的实例,就会占用内存空间。所以C++中就引用了虚基类的概念,来解决这个问题。 class?A { public: ????int?iValue; }; class?B:virtual?public?A { public: ????void?bPrintf(){coutThis?is?class?Bendl;}; }; class?C:virtual?public?A { public: ????void?cPrintf(){coutThis?is?class?Cendl;}; }; class?D:public?B,public?C { public: ????void?dPrintf(){coutThis?is?class?Dendl;}; }; void?main() { ????D?d; ????coutd.iValueendl;?//正确 } 在继承的类的前面加上virtual关键字表示被继承的类是一个虚基类,它的被继承成员在派生类中只保留一个实例。例如iValue这个成员,从类 D这个角度上来看,它是从类B与类C继承过来的,而类B C又是从类A继承过来的,但它们只保留一个副本。因此在主函数中调用d.iValue时就不 会产生错误。? ? ?? ? 虚函数 ? ?? ? 还是先看代码 class?A { public: ????void?funPrint(){coutfunPrint?of?class?Aendl;}; }; class?B:public?A { public: ????void?funPrint(){coutfunPrint?of?class?Bendl;}; }; void?main() { ????A?*p;?//定义基类的指针 ????A?a; ????B?b; ????p=a; ????p-funPrint(); ????p=b; ????p-funPrint(); } 大家以为这段代码的输出结果是什么?有的人可能会马上回答funPrint of class A 与 funPrint of class B 因为第一次输出是引用类A的实 例啊,第二次输出是引用类B的实例啊。那么我告诉你这样想就错啦,答案是funPrint of class A 与 funPrint of class A 至于为什么输出 这样的结果不在本文讨论的范围之内;你就记住,不管引用的实例是哪个类的当你调用的时候系统会调用左值那个对象所属类的方法。比如说 上面的代码类A B都有一个funPrint 函数,因为p是一个A类的指针,所以不管你将p指针指向类A或是类B,最终调用的函数都是类A的funPrint 函数。这就是静态联篇

文档评论(0)

kehan123 + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档