详解一道C++笔试题考察重载、覆盖、多态x_第1页
详解一道C++笔试题考察重载、覆盖、多态x_第2页
详解一道C++笔试题考察重载、覆盖、多态x_第3页
详解一道C++笔试题考察重载、覆盖、多态x_第4页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、详解一道c+笔试题,考察重载、覆盖、多态x 详解一道 c+ 笔试题,考察重载、覆盖、多态 c+版看到的,说是面试宝典里的题目,考察重载、覆盖、多态等概念,比较有代表性。今天早上远程辅导 yan wang 同学学习 qt 时还想到了这个题目,如果你能够正确理解这个题目,说明对于 c+ 中的函数重载、覆盖、虚函数、多态等有了正确的认识。然后呢,再来学习 qt 就顺风顺水了。 题目是酱紫的: #include iostream #include string using namespace std; class a protected: int m_data; public: a(int data

2、= 0) m_data = data; int getdata() return dogetdata(); virtual int dogetdata() return m_data; ; class b : public a protected: int m_data; public: b(int data = 1) m_data = data; int dogetdata() return m_data; ; class c : public b protected: int m_data; public: c(int data = 2) m_data = data; ; void mai

3、n() c c(10); cout c.getdata() endl; cout c.a:getdata() endl; cout c.b:getdata() endl; cout c.c:getdata() endl; cout c.dogetdata() endl; cout c.a:dogetdata() endl; cout c.b:dogetdata() endl; cout c.c:dogetdata() endl; 程序运行后的输出结果是什么? 答案是:1 1 1 1 1 0 1 1 追问一下,去掉 a 类中 dogetdata() 函数的 virtual 修饰,程序运行后的输出

4、结果是什么? 答案是:0 0 0 0 1 0 1 1 说说我对这个题目的理解。 首先我们从对象的角度来看一下。 先看 main() 函数中构造 c 对象的语句: c c(10); 这句产生下面的效果: c.m_data = 10; b1 (a)c).m_data = 0; 为什么呢? c c(10); 这行代码,定义了 c 对象,但实际上内存中有三个对象: 1 class c 的实例对象,即 c 2 c b 的派生类,会产生一个 class b 实例对象,即 (b)c 3. 由于 b 是 a 的派生类,会产生一个 a 实例对象,即 (a)c 每个对象都有 m_data 成员变量, 根据继承关系

5、,子类覆盖父类的同名成员(变量、函数), c 对象中实际上有三个同名的 m_data 变量,你通过不同的身份去看,会看到不同的 m_data 。 c 对象生成时,调用 b 、a 类的构造函数,对 b 、 a 初始化,结果就是: c 对象的 m_data = 10; b1; (a)c) 对象的 m_data = 0. 这就是我们一开始给出的效果。 明白了对象的关系和 m_data 成员的值。咱们再来看 getdata() 函数。 getdata() 函数是 class a 的一个普通方法,根据继承关系, b 、 c 类都可以访问 方法,因为 b 、 c 没有重写 getdata() ,所以通过

6、b 、 c 的对象访问 getdata() ,访问的都是 a 的 getdata() 方法。 在 getdata() 中,调用了 dogetdata() ,注意了,这是个虚函数!如果 a 的后裔重写了 dogetdata() 函数,那么这里实际上会调用到继承关系上处于最底层的那个类的 dogetdata() 函数,这就是虚函数和多态的概念。如你所见, b 重写了 dogetdata() 函数,所以当你调用 c.getdata() , b 的 dogetdata() 会被调用, (b)c).m_data 被返回。其实在 qt 中,这种用法比比皆是。 好啦,下面分析 main() 函数的输出结果。

7、 dogetdata() 带 带 virtual 关键字 关键字 c.a:getdata() / c.getdata() / c.b:getdata() / c.c:getdata() 这些语句,都是调用 a:getdata() ,最终都调用 (b)c).dogetdata(), 就是b:do,访问的是 b 的对象,它的 m_data = 1 ,所以 dogetdata() 返回 1 ,最终 getdata() 返回 1 。 c 类没有定义 dogetdata() 函数,c.dogetdata() 等同于 (b)c).dogetdata() , 访问的是 b 的对象,它的 m_data = 1

8、 ,所以 c.dogetdata() 结果是 1 。 c.a:dogetdata() ,类域作用符限定了调用 a:dogetdata(),访问 a 的对象,返回 (a)c).m_data = 0 。 c.b:dogetdata() / c.c:dogetdata() 最终都是访问 b 对象的 dogetdata() 方法, 返回都是 1 。 所以 dogetdata() 带 virtual 关键字,程序输出 1 1 1 1 1 0 1 1 。 去掉 去掉 dogetdata() 的 virtual 关键字 关键字 因为 getdata() 是 a 类的方法,而 dogetdata() 不是虚函数, a 类的 getdata() 内调用的 dogetdata() 方法只可能是 a 的对象的方法,(a)c).m_data = 0 ,所以前四个 cout 结果都是 0 。 c.dogetdata() ,c 的对象内没有实现这个函数,调用父类的,即 b 的对象的 dogetdata() 方法,访问的 m_data 是 (b)c) 对象的,是 1 。 c.a:dogetdata() ,调用 a 的方法,访问 a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论