你的c++学习路上明灯

你的c++学习路上明灯_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV16P4y1M7cX?p=10

目录

继承:

一,基本介绍:

1,好处:

2,语法:

3,

二,详细的使用

1.继承方式:

2.注意我上面的那句话,无法访问到,这就说明了,父类中私有成员也会被子类继承,只是由编译器隐藏后访问不到了。

3.继承中构造函数和析构函数的调用顺序

4.同名成员处理

5.同名静态成员处理方式和非静态处理方式一样,只不过有两种访问方式(通过对象,通过类名)

6.多继承语法

7.菱形继承

多态:

一,基本介绍

二,详细的使用

1.动态多态满足条件:

2.使用动态多态:

3.重写:函数返回值类型    函数名,参数列表完全一致称为重写。

4.多态的优点

5.纯虚函数

6.抽象类特点:

7.虚析构和纯虚析构的共性

8.实例

学习c++的人一定知道的就是c++是面向对象设计的,而面对对象的三大特性就是封装,继承和多态,我们在刚开始学习的时候就已经学过封装了,今天我们主要来学习一下多态和继承。

类的定义的出现,是具有革命性意义的,而继承和多态就是让c++变得更为方便的一笔。

继承:

一,基本介绍:

1,好处:

减少重复代码。

2,语法:

class 子类(派生类) : 继承方式 父类(基类)

3,

派生类中的成员包含两大部分:

一部分是从基类中继承来的东西,另一部分是自己增加的部分

从基类继承过来的表现其共性,而新增成员体现其个性

二,详细的使用

1.继承方式:

1)公共继承:父类权限不变;

2)保护继承:全部变成保护权限

3)私有继承:全部变为私有权限

上述三种继承方式都无法访问到分类的私有权限下的内容,但是可以访问到保护权限下的。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;//普通实现页面
//需要大量的重复代码,冗余。
//class Java {
//public:
//
//  void header() {
//      cout << "首页,公开课。。。。(公共头部)" << endl;
//  }
//  void footer() {
//      cout << "帮助中心,交流合作。。。(公共底部)" << endl;
//  }
//  void content() {
//      cout << "Java学科视频" << endl;
//  }
//
//};
//
//class Python {
//public:
//
//  void header() {
//      cout << "首页,公开课。。。。(公共头部)" << endl;
//  }
//  void footer() {
//      cout << "帮助中心,交流合作。。。(公共底部)" << endl;
//  }
//  void content() {
//      cout << "Python学科视频" << endl;
//  }
//
//};//class Cpp {
//public:
//
//  void header() {
//      cout << "首页,公开课。。。。(公共头部)" << endl;
//  }
//  void footer() {
//      cout << "帮助中心,交流合作。。。(公共底部)" << endl;
//  }
//  void content() {
//      cout << "Cpp学科视频" << endl;
//  }
//
//};//继承页面
// 重复的部分只用写一次。//公共页面类
class basepage {
public:void header() {cout << "首页,公开课。。。。(公共头部)" << endl;}void footer() {cout << "帮助中心,交流合作。。。(公共底部)" << endl;}};class Java : public basepage {
public:void content() {cout << "Java学科视频" << endl;}
};class Python : public basepage {
public:void content() {cout << "Python学科视频" << endl;}};class Cpp :public basepage {
public:void content() {cout << "Cpp学科视频" << endl;}
};void test1() {cout << "Java下载视频如下:" << endl;Java ja;ja.content();ja.footer();ja.header();cout << "------------------" << endl;cout << "Python下载视频如下:" << endl;Python py;py.content();py.footer();py.header();cout << "------------------" << endl;cout << "Cpp下载视频如下:" << endl;Cpp cp;cp.content();cp.footer();cp.header();cout << "------------------" << endl;}int main() {test1();return 0;
}

2.注意我上面的那句话,无法访问到,这就说明了,父类中私有成员也会被子类继承,只是由编译器隐藏后访问不到了。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class base {
public:int m_A;
private:int m_B;
protected:int m_C;
};class son1 :public base {
public:int m_D;};//父类所有的非静态成员属性都会被子类继承下去
//父类中的私有成员属性是被编译器给隐藏了。因此访问不到,但是确实是被继承下来了void test1() {cout << "son1 的大小为:" << sizeof(son1) << endl;//所以此处的大小是16;
}int main(){test1();return 0;
}

3.继承中构造函数和析构函数的调用顺序

创建子类对象后,先构造父类,再构造子类,析构顺序相反。

4.同名成员处理

1)子类对象可以直接访问到子类中的同名成员,

2)子类对象加作用域可以访问到父类同名成员

3)当子类与父类拥有同名的成员函数,子类会隐藏父类中的同名函数,一定要加作用域才能够访问

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class base {
public:int m_A=200;void func() {cout << "base-func()函数的调用" << endl;}void func(int a) {cout << "base-func(int a)函数的调用" << endl;}};class son1 :public base {
public:int m_A=100;void func() {cout << "son-func()函数的调用" << endl;}
};//同名成员函数处理
void test1() {son1 s;//子类对象可以直接访问到子类中的同名成员s.func();//子类对象加作用域可以访问到父类的同名成员s.base::func();//当子类对象与父类对象拥有同名的成员函数,子类会隐藏父类中的同名函数,一定要加作用域才能够访问到哦
}//同名成员属性处理
void test2() {son1 s;cout << s.m_A << endl;cout << s.base::m_A << endl;}int main() {test1();test2();return 0;
}

5.同名静态成员处理方式和非静态处理方式一样,只不过有两种访问方式(通过对象,通过类名)

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class Base {
public:static int m_A;static void func() {cout << "Base-func()的调用" << endl;}static void func(int a) {cout << "Base-func(int a)的调用" << endl;}
};int Base::m_A = 100;class Son:public Base {
public:static int m_A;static void func() {cout << "Son-func()的调用" << endl;}};int Son::m_A = 200;void test1() {//1.通过对象访问Son s;cout << "通过对象访问" << endl;cout << s.m_A << endl;cout << s.Base::m_A << endl;//2,通过类名访问cout << "通过类名访问" << endl;cout << Son::m_A << endl;//第一个 ::代表通过类名访问,第二个 ::代表作用域cout << Son::Base::m_A << endl;
}int main() {test1();return 0;
}//同名静态成员处理方式和非静态成员处理方式一样,只不过是有了两种访问方式
//通过类名和通过对象

6.多继承语法

1)c++允许一个类继承多个类(一个子类继承多个父类)

2)多继承可能会引发父类中有同名成员出现,需要加一个作用域区分

3)c++实际开发不建议用多继承(容易引发一些不必要的冲突)

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class Base1 {
public:int m_A;Base1() {m_A = 100;}};class Base2 {
public:int m_A;Base2() {m_A = 200;}
};class Son :public Base1, public Base2 {
public:int m_C;Son() {m_C = 300;}};
void test1() {Son s;//大小依然是所有的数据大小之和cout << sizeof(s) << endl;//多继承中如果父类中出现了同名情况,子类使用的时候要加作用域cout << s.Base1::m_A << endl;cout << s.Base2::m_A << endl;}int main() {test1();return 0;
}

7.菱形继承

菱形继承带来的问题:

子类继承两份相同的数据,导致资源浪费和二义性。

可以用虚继承的方法来解决

所谓虚继承每一个派生类会给自己的子类继承虚基类指针(vbptr)和一份虚基类表,表中记录了虚基类与本类与本类的偏移量。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class Animal {
public:int m_Age;
};
//虚继承就是再继承方式的前面加上virtual关键字
//虚继承就是菱形继承问题的解决方法
class sheep:virtual public Animal{};class tuo :virtual public Animal{};class sheeptuo : public sheep, public tuo{};void test1() {sheeptuo st;//两个派生类都从基类中继承了相同的数据,浪费空间,只需要留一份就好了//应用虚继承以后,两个派生类的子类只从其中继承了一份数据,且数据值以最后一次修改为准st.sheep::m_Age = 100;st.tuo::m_Age = 200;cout << st.sheep::m_Age << endl;cout << st.tuo::m_Age << endl;}
int main() {test1();return 0;
}

多态:

一,基本介绍

多态分为两类:

1)静态多态:函数重载和运算符重载,复用函数名

2)动态多态:派生类和虚函数实现运行时多态。

区别:静态多态的函数地址早绑定---编译阶段确定函数地址

动态多态的函数地址晚绑定---运行阶段确定函数地址

***c++中允许父子类之间的类型转换

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class Animal {
public://函数前面加上virtual关键字,变成虚函数,那么编译器在编译时就不能确定函数调用了//即:函数地址的先后绑定virtual void Speak() {cout << "动物在说话" << endl;}
};class Cat :public Animal {
public://重写:函数返回值类型  函数名 参数列表 完全一致//所以这里的virtual可写可不写virtual void Speak() {cout << "小猫在说话" << endl;}
};class Dog :public Animal {
public:void Speak() {cout << "小狗在说话" << endl;}
};//回调函数,提供多个选择
//c++中允许父子类之间的类型转化
void dospeak(Animal &animal) {animal.Speak();
}void test1() {Cat cat;dospeak(cat);Dog dog;dospeak(dog);}
int main() {test1();return 0;
}

二,详细的使用

1.动态多态满足条件:

1)有继承关系

2)子类重写父类的虚函数

2.使用动态多态:

父类的指针或引用指向子类对象

3.重写:函数返回值类型    函数名,参数列表完全一致称为重写。

4.多态的优点

1)代码组织结构清晰

2)可读性强

3)利于前期和后期的扩展以及维护

5.纯虚函数

virtual  返回值类型  函数名  (参数列表)=0;

6.抽象类特点:

1)无法实例化对象

2)子类必须重写抽象类中的纯虚函数,否则也属于抽象类。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class Base {
public://纯虚函数//父类的虚函数是用不上的,写了也是白写,所以就出现了纯虚函数的概念virtual void func() = 0;//一旦有了纯虚函数,该类就称作抽象类//不能实例化对象//且子类也必须重写虚函数,不然子类也成了抽象类,也无法实例化对象
};class Son : public Base {
public:void func() {cout << "func()函数的调用" << endl;}
};void test1() {//多态的意义就是//定义一个父类的指针,指向它的任意一个我们想要使用的子类对象,//从而能使我们调用到该子类对象的函数实现Base* b = new Son;b->func();delete b;
}int main() {test1();return 0;
}

7.虚析构和纯虚析构的共性

1)可以解决父类指针释放子类对象时不干净

2)都需要有具体的函数实现

区别:如果是纯虚析构,该类属于抽象类,无法实例化对象。

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;
#include<string>class Animal {
public:virtual void Speak() = 0;Animal() {cout << "Animal构造函数的调用" << endl;}//利用纯析构可以解决父类指针释放子类对象时不干净的问题/*virtual ~Animal() {cout << "Animal析构函数的调用" << endl;}*///如果不想让该类实例化对象,就写成纯虚析构virtual ~Animal() = 0;
};Animal::~Animal() {cout << "Animal纯虚析构函数的调用" << endl;
}class Cat :public Animal {
public:virtual void Speak() {cout << "小猫在说话" << endl;}Cat(string name) {cout << "Cat构造函数的调用" << endl;m_Name = new string(name);}~Cat() {cout << "Cat析构函数的调用" << endl;if (m_Name != NULL) {delete m_Name;m_Name = NULL;}}string* m_Name;
};void test1() {Animal* a = new Cat("Tom");a->Speak();//父类指针在析构的时候,并不会调用子类中的析构函数,导致子类如果有堆区属性,会出现内存泄漏delete a;
}
int main() {test1();return 0;
}

8.实例

给大家两个实例练练手

1)

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;
//制作饮品-多态class MakeDrink {
public://煮水virtual void Boil() = 0;//冲泡virtual void Brew() = 0;//倒入杯中virtual void Pour() = 0;//加入辅料 virtual void Add() = 0;void makedrink() {Boil();Brew();Pour();Add();}
};//制作咖啡
class Coffee : public MakeDrink {
public://煮水virtual void Boil() {cout << "煮咖啡水" << endl;}//冲泡virtual void Brew() {cout << "冲泡咖啡" << endl;}//倒入杯中virtual void Pour() {cout << "倒入咖啡杯中" << endl;}//加入辅料 virtual void Add() {cout << "加入牛奶和糖" << endl;}
};//制作茶
class Tea : public MakeDrink {
public://煮水virtual void Boil() {cout << "煮茶水" << endl;}//冲泡virtual void Brew() {cout << "冲泡茶" << endl;}//倒入杯中virtual void Pour() {cout << "倒入茶杯中" << endl;}//加入辅料 virtual void Add() {cout << "加入茶叶" << endl;}
};void dodrink(MakeDrink * md) {//MakeDrink * md = 子类对象md->makedrink();delete md;
}void test1() {//MakeDrink* md = new Coffee;//MakeDrink& md = new Coffee;dodrink(new Coffee);cout << "-----------------" << endl;dodrink(new Tea);}int main() {test1();return 0;
}

2)制作电脑

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;//抽象不同的零件类
//抽象CPU类
class CPU {
public:virtual void calculate() = 0;
};//抽象显卡类
class xianka{
public:virtual void display() = 0;
};//抽象内存条类
class Memory {
public:virtual void storage() = 0;
};//电脑类
class Computer {
public:Computer(CPU* cpu,xianka* xk,Memory* mem) {m_mem = mem;m_xk = xk;m_cpu = cpu;}//提供工作的函数void work() {m_cpu->calculate();m_xk->display();m_mem->storage();}~Computer() {if (m_cpu != NULL) {delete m_cpu;m_cpu = NULL;}if (m_xk != NULL) {delete m_xk;m_xk = NULL;}if (m_mem != NULL) {delete m_mem;m_mem = NULL;}}private:CPU* m_cpu;xianka* m_xk;Memory* m_mem;
};//具体厂商
//inter厂商
class IntelCPU :public CPU {
public:virtual void calculate() {cout << "Inter的CPU" << endl;}
};class Intelxianka :public xianka {
public:virtual void display() {cout << "Inter的xianka" << endl;}
};class IntelMemory :public Memory {
public:virtual void storage() {cout << "Inter的Memory" << endl;}
};//联想厂商
class Lenovo :public CPU {
public:void calculate() {cout << "Lenovo的CPU" << endl;}
};class Lenovoxianka :public xianka {
public:void display() {cout << "Lenovo的xianka" << endl;}
};class LenovoMemory :public Memory {
public:void storage() {cout << "Lenovo的Memory" << endl;}
};void test1() {//创建第一台电脑CPU* intelCpu = new IntelCPU;xianka* intelxianka = new Intelxianka;Memory* intelmem = new IntelMemory;Computer computer1(intelCpu, intelxianka, intelmem);computer1.work();cout << "------------------" << endl;//创建第二台电脑Computer computer2(new IntelCPU, new Intelxianka, new IntelMemory);computer2.work();
}
int main() {test1();return 0;
}

东西很多,希望大家认真学习,我后面会在B站上面更新讲解视频,希望大家捧场。

爱上c++的第六天(核心课程):继承和多态相关推荐

  1. c++核心编程继承和多态 、文件简单读写

    4.6 继承 继承是面向对象三大特性之一 有些类与类之间存在特殊的关系,例如下图中: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ePVg2IyK-161000214 ...

  2. 大学java专业核心课程_计算机应用技术专业核心课程有哪些?

    对于报考或者有想法学习计算机应用技术专业的学生们来说,其实,计算机应用技术专业所要学习的专业课程还是比较多的,大家应该去了解一下,那么计算机应用技术专业核心课程有哪些? 专业核心课程 1.Vf数据库应 ...

  3. 英特尔未来教育核心课程

    自12月22日起,至12月25日,为期4天的英特尔未来核心课程培训圆满结束了.     总体感觉:累并快乐着接受着全新理念的学习.

  4. 大学本科电子信息工程专业核心课程与主干课程

    核心课程          电路分析     模拟电子线路     数字电路与逻辑设计     信号与系统     射频电子线路     数字信号处理     电磁场与电磁波     微机原理与接口设 ...

  5. 华尔街英语学习软件_华尔街英语核心课程功能升级 让学员学习之旅更高效

    华尔街英语自2000年进驻中国至今,一直以科学的多元法®为众多成人英语学习者提供帮助,并通过持续的产品升级不断提升用户体验.2016年华尔街英语斥巨资研发并推出了情景喜剧式的多媒体核心课程,而近日,华 ...

  6. GIS专业核心课程电子教材配套实验数据汇总(持续更新)

    本文整合了GIS专业核心课程电子pdf教材,包括地理信息系统.地图学.遥感.摄影测量.遥感数字图像处理.工程测量.施工测量.GPS.数字测图.空间数据库.程序设计等,持续更新. 一.ArcGIS10实 ...

  7. 计算机九大核心课程,九大变化,透析IB(国际文凭)课程发展趋势

    变化1:IBDP课程框架进行了学科群的较大调整.以计算机科学为例,新的课程框架将其从原先的第五学科群调整划分入第四学科群,与物理.化学.生物等学科组成新的科学学科群.这个调整意味着IB认为计算思维(C ...

  8. Vue成大学核心课程

    作者 | 梦依丹 出品 | CSDN(ID:CSDNnews) 继维基媒体正式宣布采用 Vue.js 作为前端JS框架后,随着Vue 被更多企业青睐的同时,国内高校湖南工程职业技术学院正式把 Vue ...

  9. 世纪大学计算机专业,世纪大学本科计算机专业教学改革研讨会暨年计算机专业核心课程 (21页)-原创力文档...

    PAGE 第PAGE 21 页 共 NUMPAGES 21 页 2007年高等学校计算机专业课程教学专题研讨班<离散数学>研讨班报告 刘晓铭 TOC \o "1-3" ...

最新文章

  1. 微生物领域SCIE期刊分析(英美各40本,中国大陆0本)
  2. 年终凡尔赛,都是别人家的公司...
  3. fedora8 使用小记之:终端字体设置
  4. P1115 最大子段和
  5. python 字典定义日志用法_python中字典(Dictionary)用法实例详解
  6. linux安装redis集群+常见报错
  7. Fedora开机自动登录指定用户(root或普通用户)
  8. php操作kafka
  9. 小程序日历插件的使用
  10. 05.SpringBoot的yml配置详解
  11. 使用busybox制作根文件系统(rootfs)
  12. RedHat 7 更换 yum 源为 CentOS 或网易镜像源
  13. Maven 菜鸟教程 4 常用dos命令
  14. Windows XP SP3需要安装KB888111补丁解决方法
  15. java 加密 —— 对称加密、非对称加密、消息摘要
  16. 500. 键盘行【我亦无他唯手熟尔】
  17. mysql error 1_mysql 启动错误(InnoDB: Operating system error number 1
  18. 论文解读 X-CLIP : Expanding Language-Image Pretrained Models for General Video Recognition
  19. 软考高项 - 计算公式汇总整理
  20. css 横线中间的文字

热门文章

  1. python把日期数据转换成数字_python3时间datetime如何转换成数字?
  2. C++类与对象——封装
  3. Unraid使用记录:系统安装与基础设置
  4. 区块链、NFT与元宇宙中的稀缺性技术
  5. C# chart控件实时动态显示数据
  6. 熊猫人表情包python 代码,Python熊猫替换特殊字符
  7. Android Studio 调试的时候出现 Access denied finding property “ro.serialno“
  8. 正负数值的正则表达式
  9. PowerDesigner导入现有表结构
  10. 汉诺塔在VC控制台的图形演示