当前位置: 首页 > news >正文

c++第8天--虚继承与多态

本讲内容:

  1. 认识什么是虚继承
  2. 什么是虚函数
  3. 多态的含义

综上:虚继承就是

//虚继承就是c++为了解决多继承中的菱形继承问题而引入的一种特殊的继承方式

//虚继承就是让派生类只保留一份共同基类的成员,进而避免重复和二义性

虚继承的语法:

class A {...}

class B : virtual public A {...}

class C : virtual public A {...}

class D : public B, public C {...}

这样D对象中会有一份A的成员

虚继承就是为了解决多继承时“同一个祖先类会被继承多份”的问题。

比如:

  • 有一个A类,B和C都继承A,D又同时继承B和C。
  • 如果不用虚继承,D里面会有两份A的内容(重复了)。
  • 用了虚继承,D里面只会有一份A的内容(不重复)。

一句话总结: 虚继承就是让多继承时,最上面的公共基类只保留一份,避免重复和混乱。

#include<iostream>
using namespace std;class A{
public:int x;A() : x(100) {}
};class B : virtual public A {};
class C : virtual public A {};
class D : public B,public C {};int main()
{D d;d.x = 200;  //不会有二义性cout << d.x << endl;return 0;
}

这便就是一个典型的菱形继承问题。

下面就是一个虚继承的例子

//虚继承就是为了解决多继承时“同一个祖先类会继承多份”的问题
//下面就是一个典型的虚继承的实例
#include<iostream>
using namespace std;class Furniture{
public:Furniture(string wood);
protected:string _wood;
};Furniture :: Furniture(string wood)
{_wood = wood;
}class Sofa : virtual public Furniture{
public:Sofa(float length,string wood);
protected:float _length;
};Sofa::Sofa(float length,string wood) : Furniture(wood),_length(length) {}
//这一行的意思就是通过 Sofa类的构造函数来实现,重点在于初始化列表部分
//Furniture(wood)这里表示在构造Sofa对象的时候,先调用虚基类Furniture,并把wood参数传递给他
//_length(length)这里表示用length参数初始化Sofa类自己的成员class Bed : virtual public Furniture{
public:Bed(float width,string wood);
protected:float _width;
};Bed :: Bed(float width,string wood): Furniture(wood),_width(width) {}class Sofabed : public Sofa,public Bed{
public:Sofabed(float length,string wood,float width);void getSize();
};Sofabed::Sofabed(float length,string wood,float width) : Sofa(length,wood),Bed(width,wood),Furniture(wood) {}
void Sofabed :: getSize(){cout << "沙发床长" << _length << "m" << endl;cout << "沙发床宽" << _width << "m" << endl;cout << "沙发床材质为" << _wood << endl;
}int main()
{Sofabed sbed(1.8,"梨木",1.5);sbed.getSize();return 0;
}

现在我们再展开说一下多态

多态是什么意思呢?

这是面向对象编程中的三大特性之一,意思就是“同一种操作作用于不同的对象,可以有不同的表现。

简单的来说,就是用父类指针/引用指向子类对象,通过虚函数调用,实际执行的是之类的实现

那么多态的三要素是:

1.继承,必须有基类与派生类

2.虚函数,基类中有virtual声明的成员函数

3.父类指针/引用:用基类指针或引用指向派生类对象

#include <iostream>
using namespace std;class Animal {
public:virtual void speak() { // 虚函数cout << "动物叫" << endl;}
};class Dog : public Animal {
public:void speak() override { // 重写cout << "狗叫:汪汪" << endl;}
};void makeSound(Animal* a) {a->speak(); // 多态:实际调用的是对象的真实类型的方法
}int main() {Dog d;makeSound(&d); // 输出:狗叫:汪汪return 0;
}

虚函数

通过给函数加上virtual关键字,使成员函数成为虚函数,类中会增加了虚函数表指针的成员,虚函数表中会保存自己类的虚成员函数的地址,在通过指针或引用访问成员函数时,会先到虚函数表查找有无该成员函数,如果有就调用,没有的话就再去找其他的成员函数。

通过这种机制实现基类指针、引用调用实际指向的派生类的成员函数

多态的难点在于理解与运用

//虚函数
//虚函数式c++中实现多态的关键
#include<iostream>
using namespace std;class Person
{
public:virtual void work() {cout << "工作" << endl;}
};class Worker : public Person
{
public:void work() {cout << "工人生产" << endl;}
};class Farmer : public Person
{
public:void work() {cout << "修理" << endl;}
};class Teacher : public Person
{
public:void work() {cout << "教与学" << endl;}
};void dowork(Person& p)
{p.work();
}int main()
{//数组:把上面所有人放进去,循环调用他们的work()Person* p[3];p[0] = new Worker();p[1] = new Farmer();p[2] = new Teacher();for(int i = 0;i < 3;++i)dowork(*p[i]);for(int i = 0;i < 3;++i)delete p[i];return 0;
}

相关文章:

  • 使用C/C++的OpenCV 构建人脸识别并自动抓拍系统
  • 【DSP笔记 · 第3章】数字世界的“棱镜”:离散傅里叶变换(DFT)完全解析
  • AtCoder AT_abc410_e [ABC410E] Battles in a Row 题解
  • Hoppscotch
  • 解决在微信小程序中view组件下的text和images设置了样式display: flex; align-items: center;对不齐
  • 位运,模拟,分治,BFS,栈和哈希表
  • 基于 C 语言的图书管理系统开发详解​
  • 人工智能学习14-Numpy-数组广播机制
  • 前端异步编程基础
  • pythonday46
  • HTML+CSS 动态背景动态登录注册框
  • 模拟 AJAX 提交 form 表单及请求头设置详解
  • 大模型成长过程-预训练tokenizer
  • SQL Server 窗口函数详解:窗口行数控制的原理、关键字与应用场景
  • 鸿蒙NEXT-HMRouter,在使用router后无法跳转问题解决
  • 计算机网络-自顶向下—第四章网络层重点复习笔记
  • Python实例题:Python计算偏微分方程
  • 【Ubuntu 22.04 推荐的 apt 包管理方式详解】
  • HQL 优化:从低效到高效的蜕变之旅
  • Git可视化革命:3分钟学会用Mermaid+AI画专业分支图
  • 图书馆网站建设总结/网店推广方案范文
  • 小程序开发教程文档/seo网站关键词优化报价
  • 百度云服务器做网站稳定吗/百度推广怎么运营
  • 网站如何做seo规划/最经典的营销案例
  • 怎样做网站平台/广州新闻头条最新消息
  • 电子商务网站建设网/网络舆情监控