详细说明C++笔试题,调查超载、盖、多态
C++可见版本,他说,这本书是采访的主题,调查超载、盖、多态性等概念,比较有代表性的。今天上午,远程辅导 Yan Wang 学生们学习 Qt 时还觉得这个话题,假设你能正确地理解这一主题,注意对于 C++ 该函数重载、盖、虚函数、有了正确的认识和多态性。呢。再来学习 Qt 就顺风顺水了。
题目是酱紫的:
#include <iostream>
#include <string>
using namespace std;
class A
{
protected:
int m_data;
public:
A(int data = 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 main()
{
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 修饰,程序执行后的输出结果是什么?
答案是:0 0 0 0 1 0 1 1
说说我对这个题目的理解。
首先我们从对象的角度来看一下。
先看 main() 函数中构造 c 对象的语句:
C c(10);
这句产生以下的效果:
- c.m_data = 10;
- ((B)c).m_data = 1;
- ((A)c).m_data = 0;
为什么呢?
C c(10); 这行代码,定义了 c 对象。但实际上内存中有三个对象:
- class C 的实例对象,即 c
- 由于 C 是 B 的派生类,会产生一个 class B 实例对象,即 (B)c
- 由于 B 是 A 的派生类。会产生一个 A 实例对象,即 (A)c
每一个对象都有 m_data 成员变量, 依据继承关系,子类覆盖父类的同名成员(变量、函数)。 c 对象中实际上有三个同名的 m_data 变量。你通过不同的身份去看,会看到不同的 m_data 。
C 对象生成时。调用 B 、A 类的构造函数,对 B 、 A 初始化,结果就是:
- c 对象的 m_data = 10;
- ((B)c) 对象的 m_data = 1;
- ((A)c) 对象的 m_data = 0.
这就是我们一開始给出的效果。
明确了对象的关系和 m_data 成员的值。咱们再来看 GetData() 函数。
GetData() 函数是 class A 的一个普通方法。依据继承关系, B 、 C 类都可以訪问 GetData() 方法,由于 B 、 C 没有重写 GetData() 。所以通过 B 、 C 的对象訪问 GetData() ,訪问的都是 A 的 GetData() 方法。
在 GetData() 中。调用了 doGetData() ,注意了,这是个虚函数!假设 A 的后裔重写了 doGetData() 函数,那么这里实际上会调用到继承关系上处于最底层的那个类的 doGetData() 函数,这就是虚函数和多态的概念。如你所见。 B 重写了 doGetData() 函数,所以当你调用 c.GetData() 。 B 的 doGetData() 会被调用, ((B)c).m_data 被返回。
事实上在 Qt 中,这样的使用方法比比皆是。
好啦。以下分析 main() 函数的输出结果。
doGetData() 带 virtual keyword
c.A::GetData() / c.GetData() / c.B::GetData() / c.C::GetData()
这些语句,都是调用 A::GetData() 。终于都调用 ((B)c).doGetData(), 就是B::doGetData() ,訪问的是 B 的对象,它的 m_data = 1 。所以 doGetData() 返回 1 。终于 GetData() 返回 1 。
C 类未定义 doGetData() 函数,c.doGetData() 等同于 ((B)c).doGetData() , 訪问的是 B 的对象,它的 m_data = 1 。所以 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 keyword,程序输出 1 1 1 1 1 0 1 1 。
去掉 doGetData() 的 virtual keyword
由于 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 的对象 ((A)c).m_data ,结果是 0 。
c.B::doGetData() / c.C::doGetData() 。调用 B 的方法。訪问 B 的对象 ((B)c).m_data 。结果为 1 。
所以,终于结果是:0 0 0 0 1 0 1 1
我不知道说清楚没有什么?
版权声明:本文博客原创文章,博客,未经同意,不得转载。
详细说明C++笔试题,调查超载、盖、多态的更多相关文章
- C/C++ 笔试题
/////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程 ...
- C/C++笔试题(很多)
微软亚洲技术中心的面试题!!! .进程和线程的差别. 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2 ...
- 剑指Offer——京东实习笔试题汇总
剑指Offer--京东实习笔试题汇总 编程题1 题目的详细信息已经记不住,只能大致描述一下,就是求最有价值的的委托信息. n.s.B.S其中n代表委托信息,s要求的最有价值的委托信息的个数,B代表买入 ...
- 【Android】一道Android OpenGL笔试题
一道Android OpenGL笔试题 SkySeraph May. 5th 2016 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sky ...
- ThoughtWorks西邮暑期特训营 -- JavaScript在线笔试题
ThoughtWorks 公司在西邮正式开办的只教女生前端开发的女子卓越实验室已经几个月过去了,这次计划于暑期在西邮内部开展面向所有性别所有专业的前端培训. 具体官方安排请戳:ThoughtWorks ...
- 收藏所用C#技术类面试、笔试题汇总
技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补 ...
- 10道C++输出易错笔试题收集
下面这些题目都是我之前准备笔试面试过程中积累的,大部分都是知名公司的笔试题,C++基础薄弱的很容易栽进去.我从中选了10道简单的题,C++初学者可以进来挑战下,C++大牛也可以作为娱乐玩下(比如下面的 ...
- 嵌入式Linux C笔试题积累(转)
http://blog.csdn.net/h_armony/article/details/6764811 1. 嵌入式系统中断服务子程序(ISR) 中断是嵌入式系统中重要的组成部分,这导致了很 ...
- [NOIp 1998 提高组]Probelm 2 连接多位数【2011百度实习生笔试题】
/*====================================================================== [NOIp 1998 提高组]Probelm 2 连接 ...
随机推荐
- Java EE (7) -- Java EE 6 Enterprise Architect Certified Master(1z0-807)
Application Design Concepts and Principles Identify the effects of an object-oriented approach to sy ...
- Moran’s I空间统计中出现内存溢出的问题
在经济学.资源管理.生物地理学.政治地理学和人口统计等领域,经常会有如下的研究需求: 研究区域中的富裕区和贫困区之间的最清晰边界在哪里? 研究区域中存在可以找到异常消费模式的位置吗? 研究区域中意想不 ...
- [置顶] 最优间隔分类器、原始/对偶问题、SVM的对偶问题——斯坦福ML公开课笔记7
转载请注明:http://blog.csdn.net/xinzhangyanxiang/article/details/9774135 本篇笔记针对ML公开课的第七个视频,主要内容包括最优间隔分类器( ...
- 【夸QT十一】外来物品:通用脚本帮助Web运行基础Linux命令
需求分析: 需要注意的是在这里第一次,这个人是不是QT系列文章,它是关于Web的,之所以写这篇文章.这是因为碍着Web相关开发时间,而且往往涉及linux与底层指令处理.例如,创建一个文件夹,删除一个 ...
- 【Android进阶】Android面试题目整理与讲解(一)
这一篇文章专门整理一下研究过的Android面试题,内容会随着学习不断的增加,如果答案有错误,希望大家可以指正 1.简述Activity的生命周期 当Activity开始启动的时候,首先调用onCre ...
- CSS+DIV+HTML(一)--HTML总结
一.定义 HTML(Hyper Text Markup Language),标记语言. 二.主要内容: HTML元素分为三类:块级标签.内联标签.可变标签.差别在于: 块级元素:在默认情况下会换行显示 ...
- repeater操作
protected void rpRole_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ...
- Phone Number 2010年山东省第一届ACM大学生程序设计竞赛
Phone Number Time Limit: 1000MS Memory limit: 65536K 题目描述 We know that if a phone number A is anothe ...
- jQuery插件主要有两种扩展方式
jQuery插件主要有两种扩展方式: 扩展全局函数方式. 扩展对象方法方式. 扩展全局函数方式 扩展全局函数方式定义的插件,即类级别插件,可以通过jQuery.extend()来进行定义.定义格式为: ...
- 【转】Directx11 SDK文档
原文地址:http://blog.csdn.net/cmt100/article/details/6343274 总结 这是一个初步的教程.我们将通过必要的步骤来创建一个Win32 Applicati ...