Sirius' blog Sirius' blog
首页
  • 学习笔记

    • 《C++》
    • 《MATLAB》
    • 《Python》
  • 学习笔记

    • 《Git》
    • 《CMake》
  • 技术文档
  • 博客搭建
  • 学习
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Sirius0v0

怕什么真理无穷,进一寸有一寸的欢喜
首页
  • 学习笔记

    • 《C++》
    • 《MATLAB》
    • 《Python》
  • 学习笔记

    • 《Git》
    • 《CMake》
  • 技术文档
  • 博客搭建
  • 学习
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础

    • 程序的内存模型
    • CC++指针
    • CC++引用
    • CC++类与对象
    • CC++运算符重载
    • CC++继承
    • CC++多态
      • 基本概念
      • 案例1:谁在说话?
      • 纯虚函数和抽象类
        • 制作饮品的一个案例
      • 虚析构和纯虚析构
    • CC++文件操作
  • Cpp小记
  • C++学习笔记-220705-V1
  • 进阶

  • 奇思妙用

  • 库的使用

  • 《C++》学习笔记
  • 基础
Sirius0v0
2023-07-07
目录

CC++多态

# C/C++: 多态

# 基本概念

多态分为两类:

  • 静态多态:函数重载、运算符重载等,复用函数名;
  • 动态多态:派生类和虚函数实现运行时多态。

静态多态与动态多态的区别:

  • 静态多态函数地址早绑定——编译阶段确定
  • 动态多态函数地址晚绑定——运行阶段确定

# 案例1:谁在说话?

class Animal
{
public:
    void speak(){cout<<"动物在说话";}
};

class Cat : public Animal
{
public:
    void speak(){cout<<"猫在说话";}
};

此时定义函数让其说话

void doSpeak(Animal &animal)
{
    animal.speak();
}

调用函数如下:

void test()
{
    Cat cat;
    doSpeak(cat);
}

我们创建了子类对象,传入了需要父类形参的函数里,到底是谁在说话?

由于地址早绑定,编译阶段即确定是Animal,因而没有实现我们的需求。如果想让猫说话,需要函数地址晚绑定,利用虚函数实现。

为父类中的函数添加virtual关键字即可。

动态多态满足条件

  1. 有继承关系
  2. 子类重写父类的虚函数

动态多态的使用

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

# 纯虚函数和抽象类

纯虚函数语法:virtual 返回值类型 函数名 (参数列表) = 0;

当类中有了纯虚函数,这个类就称为抽象类,其特点为

  • 无法实例化对象
  • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类

# 制作饮品的一个案例

制作饮品的抽象类:

class AbstractDrinking
{
public:
    // 煮水
    virtual void Boil() = 0;
	// 冲泡
    virtual void Brew() = 0;
    // 加辅料
    virtual void PutSth() = 0;
    // 制作饮品
    void makeDrink(){
        Boil();
        Brew();
        PutSth();
    }
}

制作咖啡则可以如下写:

class Coffee :public AbstractDrinking
{
public:
    virtual void Boil()
    {cout << "煮农夫山泉";}
    virtual void Brew()
    {cout << "冲咖啡";}
    virtual void PutSth()
    {cout << "加入牛奶和糖";}
}

写一个制作函数

void DoWork(AbstractDrinking* abs)
{
    abs->makeDrink();
    delete abs;
}

则可以轻松且清晰地”制作咖啡“

void test()
{
    DoWork(new Coffee);
}

# 虚析构和纯虚析构

多态使用过程中,如果有子类属性开辟到堆区,那么父类指针在释放资源时无法调用到子类的析构代码,造成内存泄漏的风险。

解决方案:将父类的析构函数改为虚析构或纯虚析构。

  • 虚析构语法:virtual ~ClassName(){};
  • 纯虚析构语法:virtual ~ClassName() = 0;
    • 声明后需要实现
编辑 (opens new window)
#Cpp
上次更新: 2023/08/09, 13:21:24
CC++继承
CC++文件操作

← CC++继承 CC++文件操作→

最近更新
01
ipopt优化库配置及使用
07-21
02
ubuntu离线安装包的方法
07-21
03
其它控件的使用
03-05
更多文章>
Theme by Vdoing | Copyright © 2020-2024 Sirius0v0 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式