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

【C++基础】--多态

深入了解多态

  • 一、认识多态
  • 二、定义及实现
    • 构成条件
    • 虚函数重写
    • C++11 override 和 final
      • final:修饰虚函数,表示该虚函数不能再被重写
      • override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。
  • 三、抽象类
    • 概念
  • 四、多态的实现原理
    • 扩展

在这里插入图片描述

一、认识多态

多态作为面向对象三大特征之一,指的是一个接口可以有多个不同的实现方式。简单说,就是同一个函数或方法调用,可以根据上下文的不同执行不同的功能。在C++中,多态主要是通过基类的指针或引用,来调用子类的重写函数实现。C++中的多态主要是通过虚函数来实现。
示例:

#include <iostream>
using namespace std;class Base {
public:virtual void show() {cout << "Base class show function" << endl;}
};class Derived : public Base {
public:void show() override {cout << "Derived class show function" << endl;}
};int main() {Base* basePtr;Derived derivedObj;basePtr = &derivedObj;basePtr->show();  // 输出:Derived class show functionreturn 0;
}

在上述代码中,通过基类指针basePtr,调用子类derivedObj的show方法。这就是多态。

二、定义及实现

构成条件

在继承中构成多态满足以下条件:
1.必须通过基类的指针或者引用调用虚函数
2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

在这里插入图片描述

虚函数重写

虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。

class Person {
public:virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:virtual void BuyTicket() { cout << "买票-半价" << endl; }
/*注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用*/
/*void BuyTicket() { cout << "买票-半价" << endl; }*/
};
void Func(Person& p)
{ p.BuyTicket(); }
int main()
{Person ps;Student st;Func(ps);Func(st);return 0;}

C++11 override 和 final

final:修饰虚函数,表示该虚函数不能再被重写

class Car
{
public:virtual void Drive() final {}
};
class Benz :public Car
{
public:virtual void Drive() {cout << "Benz-舒适" << endl;}
};

override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。

class Car{
public:virtual void Drive(){}
};
class Benz :public Car {
public:virtual void Drive() override {cout << "Benz-舒适" << endl;}
};

三、抽象类

概念

在虚函数的后面写上=0,则这个虚函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫做接口),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对对象。纯虚函数规范了派生类重写,另外纯虚函数更体现了接口继承。

class Car
{
public:virtual void Drive() = 0;
};
class Benz :public Car
{
public:virtual void Drive(){cout << "Benz-舒适" << endl;}
};
class BMW :public Car
{
public:virtual void Drive(){cout << "BMW-操控" << endl;}
};
void Test()
{Car* pBenz = new Benz;pBenz->Drive();Car* pBMW = new BMW;pBMW->Drive();
}

四、多态的实现原理

多态的实现原理,主要是虚函数、虚函数表和虚函数指针方向。
多态通过虚函数实现。通过虚函数,子类可以重写父类的方法,当通过基类指针或引用调用时,会根据对象的实际类型调用对应的函数实现。
更深层次的原理,是通过虚表(vtable)和虚表指针(vptr)机制实现的。虚表是一个函数指针数组,包含了该类的所有虚函数的地址,而虚表指针存储在对象实例中,指向属于该对象的虚表。

扩展

  • 虚函数和重写:在基类中使用关键字virtual声明虚函数后,在子类中可以重写这个函数
  • 虚表(vtable):每个包含虚函数的类都会有一个虚表(vtable),这个虚表在编译时生成。他包含该类所有虚函数的指针。对于每个类(而不是每个对象),编译器会创建一个唯一的虚表。
  • 虚表指针(vptr):每个包含虚函数的对象实例会有一个隐藏的虚表指针(vptr),他在对象创建时自动初始化,指向该类的虚表。不同类型的对象,其虚表指针会指向不同的虚表。例如
  • 多态的调用机制:当通过基类指针或引用调用虚函数时,程序会通过该类指针或引用找到对应的对象,然后通过虚表指针找到正确的虚表中的函数地址,最终调用适当的函数实现,这样程序能够在运行时决定调用哪一个函数实现。
    实例:
class Base {
public:virtual void show() {std::cout << "Base show" << std::endl;}
};class Derived : public Base {
public:void show() override {std::cout << "Derived show" << std::endl;}
};void demonstratePolymorphism(Base &obj) {obj.show();  // 依赖于实际对象的类型
}int main() {Base b;Derived d;demonstratePolymorphism(b);  // 输出 "Base show"demonstratePolymorphism(d);  // 输出 "Derived show"return 0;
}
http://www.lryc.cn/news/591983.html

相关文章:

  • web域名解析
  • 信息论至AI实践:交叉熵的原理全景与应用深度解析
  • Github库镜像到本地私有Gitlab服务器
  • 您的企业需要服务台经理吗?-ManageEngine卓豪
  • 《5分钟开发订单微服务!飞算JavaAI实战:IDEA插件安装→空指针修复→K8s部署全流程》
  • 3C电子产品蓝光三维扫描检测方案-中科米堆CASAIM
  • 机器视觉的布料丝印应用
  • Duckdb处理excel文件
  • 【实战】一次出口连接数超限事故引发的架构反思:强制代理、NAT 网关与大厂最佳实践
  • Python网络爬虫实现selenium对百度识图二次开发以及批量保存Excel
  • LangChain 源码剖析(七)RunnableBindingBase 深度剖析:给 Runnable“穿衣服“ 的装饰器架构
  • Yoga Air 32,Yoga Air 32,Yoga AIO 9 32IRH8(F0HH,F0HJ)一体机电脑原厂Win11系统镜像
  • 服务攻防-Java组件安全FastJson高版本JNDI不出网C3P0编码绕WAF写入文件CI链
  • AI产品经理面试宝典第36天:AI+旅游以及行业痛点相关面试题的指导
  • sql注入以及Python二分查找
  • 创建型模式
  • MinIO 分布式文件系统
  • 第二篇 html5和css3开发基础与应用
  • 【论文阅读】BEVFusion: A Simple and Robust LiDAR-Camera Fusion Framework
  • poi-excel-添加水印
  • 20250718【顺着234回文链表做两题反转】Leetcodehot100之20692【直接过12明天吧】今天计划
  • Vue导出Html为Word中包含图片在Microsoft Word显示异常问题
  • Excel批量生成SQL语句 Excel批量生成SQL脚本 Excel拼接sql
  • FastExcel:革新Java生态的高性能Excel处理引擎
  • 2.3 前端-ts的接口以及自定义类型
  • VUE目录结构详解
  • html5+css3+canvas纯前端4字方形LOGO生成器
  • Edge浏览器的多用户配置文件功能
  • java前端基础--HTMLCSS、JavaScript、Vue、Ajax
  • 【移动端知识】移动端多 WebView 互访方案:Android、iOS 与鸿蒙实现