从生活角度学习c++
通过共同讨论解决遇到的知识性问题,及时的把考试与提高班学习无缝连接,把知识与生活相联系,这样既丰富了生活、又培养了乐趣,更有助于理解,提高学习效率。
第一:指针、引用;例如有十个房间,房间的门牌号可以说就是指针,编号在变,指针在变。指针可以为空,指针是个变量,系统为其分配了内存空间,即计算机中指向一块内存,内容为所指的内存的地址(编号)
引用是每个房间的物品,引用不能为空。引用是C++中的概念,我们刚开始学习很容易把引用和指针混淆一起。例题:n是m的一个引用(reference),m是被引用物(referent)。intm;
int&n=m;n相当于m的别名(绰号),对n的任何操作就是对m的操作。例如有人名叫王小毛,他的绰号是“三毛”。说“三毛”怎么怎么的,其实就是对王小毛说三道四。所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。
指针与引用的主要区别:
指针能够毫无约束地操作内存中的任何东西,尽管指针功能强大,但是非常危险。就象一把刀,它可以用来砍树、裁纸、修指甲、理发等等,谁敢这样用?如果的确只需要借用一下某个对象的“别名”,那么就用“引用”,而不要用“指针”,以免发生意外。比如说,某人需要一份证明,本来在文件上盖上公章的印子就行了,如果把取公章的钥匙交给他,那么他就获得了不该有的权利。
第二:继承、多肽、派生
在日常生活当中常见,父亲继承爷爷的相貌、血型等,儿子继承父亲的相貌、血型,这种关系很容易的让我们理解基类(父类),父亲为从爷爷那派生而来即派生类(子类),同样儿子也是父亲的派生类(子类)。
继承:作为儿子的角度来看我们是从父亲那继承的,从长辈角度晚辈是派生的
多继承:可以理解为一个研究员既有研究生的特征,又具有教师的特征,描述事物具有的多种特征。
多肽:就是同一事物在不同条件下的不同表现形式:生活中水在常温下是液体,在100摄氏度以上就是气体,在0摄氏度以下就是固体。
二义性问题:爷爷有连个儿子:父亲和叔叔,爷爷有门电焊技术,传授给了父亲和叔叔,当儿子想学习时,既想从父亲那学习又想从叔叔那学习,这样就可能出现重复,即程序中出现二义性问题,由于多继承中派生出拥有多个基类,如果多个基类中拥有同名的成员,那么,派生类在继承各个基类的成员之后,当调用该派生类成员时,由于该成员标示符不唯一,出现二义性。
第三:类模板:问题域中的事物存在一定的相似性,与之对应,设计的类和类的成员也将表现出相似性,通过抽象将这些相似的类和函数的共性提取出来,用一种统一的方式来描述,形成类模板,
生活中:城市里来来往往的公交车,这个公交车站牌(等车的地方)对于所有可以停车到这的公交车来说这就是公交车的一个类模板,来了公交车就可以停靠的
第四:虚基类:当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类虚基类,在说明其作用前先看一段代码
classA
{
public:
intiValue;
};
classB:publicA
{
public:
voidbPrintf(){cout<<"ThisisclassB"<<endl;};
};
classC:publicA
{
public:
voidcPrintf(){cout<<"ThisisclassC"<<endl;};
};
classD:publicB,publicC
{
public:
voiddPrintf(){cout<<"ThisisclassD"<<endl;};
};
voidmain()
{
Dd;
cout<<d.iValue<<endl;//错误,不明确的访问
cout<<d.A::iValue<<endl;//正确
cout<<d.B::iValue<<endl;//正确
cout<<d.C::iValue<<endl;//正确
}
从代码中可以看出类BC都继承了类A的iValue成员,因此类BC都有一个成员变量iValue,而类D又继承了BC,这样类D就有一个重名的成员iValue(一个是从类B中继承过来的,一个是从类C中继承过来的).在主函数中调用d.iValue因为类D有一个重名的成员iValue编译器不知道调用从谁继承过来的iValue所以就产生的二义性的问题.正确的做法应该是加上作用域限定符d.B::iValue表示调用从B类继承过来的iValue。不过类D的实例中就有多个iValue的实例,就会占用内存空间。所以C++中就引用了虚基类的概念,来解决这个问题。
classA
{
public:
intiValue;
};
classB:virtualpublicA
{
public:
voidbPrintf(){cout<<"ThisisclassB"<<endl;};
};
classC:virtualpublicA
{
public:
voidcPrintf(){cout<<"ThisisclassC"<<endl;};
};
classD:publicB,publicC
{
public:
voiddPrintf(){cout<<"ThisisclassD"<<endl;};
};
voidmain()
{
Dd;
cout<<d.iValue<<endl;//正确
}
在继承的类的前面加上virtual关键字表示被继承的类是一个虚基类,它的被继承成员在派生类中只保留一个实例。例如iValue这个成员,从类D这个角度上来看,它是从类B与类C继承过来的,而类BC又是从类A继承过来的,但它们只保留一个副本。因此在主函数中调用d.iValue时就不会产生错误。
虚函数
还是先看代码
classA
{
public:
voidfunPrint(){cout<<"funPrintofclassA"<<endl;};
};
classB:publicA
{
public:
voidfunPrint(){cout<<"funPrintofclassB"<<endl;};
};
voidmain()
{
A*p;//定义基类的指针
Aa;
Bb;
p=&a;
p->funPrint();
p=&b;
p->funPrint();
}
大家以为这段代码的输出结果是什么?有的人可能会马上回答funPrintofclassA与funPrint
ofclassB因为第一次输出是引用类A的实例啊,第二次输出是引用类B的实例啊。那么我告诉你
这样想就错啦,答案是funPrintofclassA与funPrintofclassA至于为什么输出这样的结
果不在本文讨论的范围之内;你就记住,不管引用的实例是哪个类的当你调用的时候系统会调用左
值那个对象所属类的方法。比如说上面的代码类AB都有一个funPrint函数,因为p是一个A类的
指针,所以不管你将p指针指向类A或是类B,最终调用的函数都是类A的funPrint函数。这就是静
态联篇,编译器在编译的时候就已经确定好了。可是如果我想实现跟据实例的不同来动态决定调用
哪个函数呢?这就须要用到虚函数(也就是动态联篇)
classA
{
public:
virtualvoidfunPrint(){cout<<"funPrintofclassA"<<endl;};
};
classB:publicA
{
public:
virtualvoidfunPrint(){cout<<"funPrintofclassB"<<endl;};
};
voidmain()
{
A*p;//定义基类的指针
Aa;
Bb;
p=&a;
p->funPrint();
p=&b;
p->funPrint();
}
在基类的成员函数前加virtual关键字表示这个函数是一个虚函数,所谓虚函数就是在编译的时候不确定要调用哪个函数,而是动态决定将要调用哪个函数,要实现虚函数必须派生类的函数名与基类相同,参数名参数类型等也要与基类相同。但派生类中的virtual关键字可以省略,也表示这是一个虚函数。下面来解决一下代码,声明一个基类的指针(必须是基类,反之则不行)p,把p指向类A的实例a,调用funPrint函数,这时系统会判断p所指向的实例的类型,如果是A类的实例就调用A类的funPrint函数,如果是B类的实例就调用B类的funPrint函数。
纯虚函数它只是声明一个函数但不实现它,让派生类去实现它,其实这也很好理解。
classVehicle
{
public:
virtualvoidPrintTyre()=0;//纯虚函数是这样定义的
};
classCamion:publicVehicle
{
public:
virtualvoidPrintTyre(){cout<<"Camiontyrefour"<<endl;};
};
classBike:publicVehicle
{
public:
virtualvoidPrintTyre(){cout<<"Biketyretwo"<<endl;};
};
voidmain()
{
Camionc;
Bikeb;
b.PrintTyre();
c.PrintTyre();
}
如上代码,定义了一个交通工具类(Vehicle),类中有一函数可打印出交通工具的轮胎个数,但
交通工具很多轮胎个数自然也就不确定,所以就把它定义为纯虚函数,也就是光定义函数名不去实
现它,类Camion继承了Vehicle并实现了里面的代码,打印出有4个轮胎。Bike类也是一样。有一
点须要注意一下,纯虚函数不能实化化,但可以声明指针。
总结
虚基类
1,一个类可以在一个类族中既被用作虚基类,也被用作非虚基类。
2,在派生类的对象中,同名的虚基类只产生一个虚基类子对象,而某个非虚基类产生各自的
子对象。
3,虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的。
4,最派生类是指在继承结构中建立对象时所指定的类。
5,派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用;如果未列出,
则表示使用该虚基类的缺省构造函数。
6,从虚基类直接或间接派生的派生类中的构造函数的成员初始化列表中都要列出对虚基类构
造函数的调用。但只有用于建立对象的最派生类的构造函数调用虚基类的构造函数,而该派生类
的所有基类中列出的对虚基类的构造函数的调用在执行中被忽略,从而保证对虚基类子对象只初
始化一次。
7,在一个成员初始化列表中同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造
函数先于非虚基类的构造函数执行。
虚函数
1,虚函数是非静态的、非内联的成员函数,而不能是友元函数,但虚函数可以在另一个类中
被声明为友元函数。
2,虚函数声明只能出现在类定义的函数原型声明中,而不能在成员函数的函数体实现的时候
声明。
3,一个虚函数无论被公有继承多少次,它仍然保持其虚函数的特性。
4,若类中一个成员函数被说明为虚函数,则该成员函数在派生类中可能有不同的实现。当使
用该成员函数操作指针或引用所标识的对象时,对该成员函数调用可采用动态联编。
5,定义了虚函数后,程序中声明的指向基类的指针就可以指向其派生类。在执行过程中,该
函数可以不断改变它所指向的对象,调用不同版本的成员函数,而且这些动作都是在运行时动态
实现的。虚函数充分体现了面向对象程序设计的动态多态性。纯虚函数版本的成员函数,而且这
些动作都是在运行时动态实现的。虚函数充分体现了面向对象程序设计的动态多态性。
纯虚函数
1,当在基类中不能为虚函数给出一个有意义的实现时,可以将其声明为纯虚函数,其实现留
待派生类完成。
2,纯虚函数的作用是为派生类提供一个一致的接口。
3,纯虚函数不能实化化,但可以声明指针。
第五:运算符重载:就是编译器不知道运算规则,由你来制定规则比如结构体point{intx,inty}你直接用两个结构体相加,编译器就不知道怎么加,所以要咱们要重载+号,告诉编译器运算规则,实现两个结构体间的运算
不同数据类型之间的运算,还有复合数据类型参与的运算都要运算符重载
从生活角度学习c++相关推荐
- 从生活角度学习应用程序、虚拟目录、应用程序池(解惑篇)
转自:http://blog.csdn.net/zwk626542417/article/details/9819343 概要 应用程序.虚拟目录.应用程序池这三个概念在上一篇中<一看就会之-利 ...
- 豪情-关于生活工作学习之感悟-第三篇
以下是我在群内交流时的回答或平常生活中的一些感悟,还有就是比较经典励志的片段收藏. 由于个人知识面有限,不具有普遍性,仅供参考. 另外我感觉,互联网个人的经验或这一代人的努力,应该通过文字的形式来记录 ...
- 基础才是重中之重~通过人类的生活来学习Delegate
一个人(people),在他60岁之后,就宣布进入晚年了,在这个期间要多注意身体,多体检. namespace NET基础才是重中之重{/// <summary>/// 人类/// < ...
- 开发日记 第一节 生活中学习的一些资源链接(汇总)
第一节 生活中学习的一些资源链接(汇总) 序 一.学习平台 二.英语学习 三.IT编程学习 四.软件资源 五.其它学习资源 序 推荐使用电脑端打开本页面的一些指向链接,手机端打开会有时间较长的页面转码 ...
- 穷查理宝典-----第二章 (芒格的生活、学习决策方法)
穷查理宝典-----第二章 (芒格的生活.学习决策方法) 穷查理宝典-----第二章 (芒格的生活.学习决策方法) 芒格进行商业分析和评估的"多元思维模型" 芒格的投资评估过程 穷 ...
- 丁晓钟怎么样_六级答案_丁晓钟:如何从各个角度学习四六级阅读理解?_沪江英语...
丁晓钟:全国著名四六级辅导专家,恩波特聘优秀核心教师,六级辅导实力派领军人物,"阅读超精读"和"词汇超链接"学习理念的创始人.全国唯一在同一城市招生超过两千人的 ...
- 养成好的生活和学习习惯
[生活习惯] 社会的生活分了很多层次,过着哪种生活都要有一个好的习惯,有时候是一个好的习惯决定了你过哪一种生活. 一个好的习惯可以改变人的一生,一个坏的习惯也可以改变一生. 谈论到好坏习惯我们可以想到 ...
- 关于生活工作学习之感悟-第一篇
文章的起因:这是平常在群内交流时的一些积累,后来经由 [霸天] 整理,然后给我启发,遂成文以分享之.欢迎拍砖~! 1. 关于面试时 建议面试前了解公司的背景,包括成长历史,企业文化,愿景,创始人的故事 ...
- python课程的中期报告_“对话生活”项目学习中期总结
一. 这段时间大家在读哪本书?有什么感受? 这段时间正在读<项目式教学>和<用生命的母语做教育>,两本书结合起来看的.总的来说,我觉着陶行知和杜威的思想正好就是实施项目式学习的 ...
- 豪情-关于生活工作学习之感悟-第二篇
1. 关于感动 你的点滴感动,是我们以后进步的动力,也是大伙更有激情交流力量的源泉. 真因为这份感动,我们在携手向前,向着同一个目标或梦想出发. 无论怎么样,群是你最后寻找帮助的小窝,是你寻找生活勇气 ...
最新文章
- C++拾趣——STL容器的插入、删除、遍历和查找操作性能对比(Windows VirtualStudio)——删除
- AI化身监工,上班还能摸鱼吗?
- 六、使用数组模拟栈的思路及代码实现
- 【 Vivado 】输出延迟约束实例
- C# 整数与字符串拼接之间的装箱操作
- ssh_exchange_identification: Connection closed by remote host 解决方法
- 深度解密Go语言之pprof
- Web前端开发笔记——第四章 JavaScript程序设计 第五节 数组
- css3半空心圆_15个超强悍的CSS3圆盘时钟动画赏析
- python封装 继承 多态 举例_python面向对象中的封装、继承、多态
- 递归-汉诺塔(代码、分析、汇编)
- [国家集训队] 特技飞行
- python函数之作用域
- 使用phpstudy中的apache进行虚拟主机的配置(自定义网站名进行访问,如http://wei.com)
- SiteMesh框架统一布局用法介绍
- 【高频电子线路】[模型]LC并联谐振回路(第2章 谐振功率放大器)
- java图像预处理_图像预处理(一)基本特征提取
- 马小云:利用信息差赚钱的暴利创业项目 ,批量开店月入3万
- quartus dcfifo操作
- moment时区转换
热门文章
- rendered使用效果
- 中国电信无线网服务器,中国电信网上营业厅
- java计算机毕业设计海康物流MyBatis+系统+LW文档+源码+调试部署
- Java在后台获取USB二维码扫描枪扫描的内容
- HTTPClient网络异常:java.lang.IllegalStateException: Content has been consumed
- CSAPP 第三版 第四章 家庭作业and so on
- miRNA 在基因调控中的作用
- 逆向app - 简单apk工具的安装
- Java每日算法--罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
- 【File类、递归】