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

C++ 多态性(Polymorphism)和 虚函数(Virtual Functions)

在 C++ 中,多态性(Polymorphism)是面向对象编程的一个重要概念,它允许通过基类指针或引用来调用派生类对象的特定方法。虚函数(Virtual Functions)是实现多态性的一种机制,通过在基类中声明虚函数,并在派生类中进行重写,可以实现动态绑定,使程序在运行时确定应该调用哪个函数。

下面我将详细解释多态性和虚函数的概念,并提供一个示例来说明它们的用法。

  1. 多态性:
    多态性是指同一种操作或方法在不同的对象上产生不同的行为。在面向对象编程中,多态性通过继承和重写函数来实现。它允许我们使用基类的指针或引用来调用派生类的特定方法,从而实现针对不同对象的不同行为。

  2. 虚函数:
    虚函数是在基类中声明的函数,可以在派生类中进行重写。通过在基类函数声明中添加 virtual 关键字,可以指示编译器在运行时进行动态绑定,根据对象的实际类型选择调用哪个函数。

    以下是一个示例,展示了多态性和虚函数的用法:

  #include <iostream>class Shape {public:virtual void draw() {std::cout << "绘制一个形状" << std::endl;}};class Circle : public Shape {public:void draw() override {std::cout << "绘制一个圆形" << std::endl;}};class Rectangle : public Shape {public:void draw() override {std::cout << "绘制一个矩形" << std::endl;}};int main() {Shape* shape1 = new Circle();Shape* shape2 = new Rectangle();shape1->draw(); // 输出:绘制一个圆形shape2->draw(); // 输出:绘制一个矩形delete shape1;delete shape2;return 0;}

在这个示例中,我们定义了一个基类 Shape,并在其中声明了一个虚函数 draw。然后,派生类 CircleRectangle 分别重写了 draw 函数。

main 函数中,我们使用 Shape 的指针分别创建了 CircleRectangle 的对象,并通过基类指针调用它们的 draw 函数。由于 draw 函数在基类中被声明为虚函数,因此在运行时会根据对象的实际类型选择调用相应的函数。这就实现了多态性,使得我们可以通过基类指针来调用派生类的特定函数。

输出结果为:

   绘制一个圆形绘制一个矩形

当我们有一个基类 Animal 和两个派生类 DogCat 时,我们可以使用多态性和虚函数来实现不同类型的动物发出不同的声音。

#include <iostream>class Animal {
public:virtual void makeSound() {std::cout << "动物发出声音" << std::endl;}
};class Dog : public Animal {
public:void makeSound() override {std::cout << "狗发出汪汪声" << std::endl;}
};class Cat : public Animal {
public:void makeSound() override {std::cout << "猫发出喵喵声" << std::endl;}
};int main() {Animal* animal1 = new Dog();Animal* animal2 = new Cat();animal1->makeSound(); // 输出:狗发出汪汪声animal2->makeSound(); // 输出:猫发出喵喵声delete animal1;delete animal2;return 0;
}

在这个示例中,Animal 是一个基类,其中的 makeSound 函数被声明为虚函数。派生类 DogCat 分别重写了 makeSound 函数。在 main 函数中,我们使用基类指针分别创建了 DogCat 的对象,并通过这些指针调用了 makeSound 函数。

由于 makeSound 函数在基类中被声明为虚函数,因此在运行时会根据对象的实际类型选择调用相应的函数。这就实现了多态性,使得我们可以通过基类指针来调用派生类的特定函数。

输出结果为:

狗发出汪汪声
猫发出喵喵声

通过多态性和虚函数,我们可以根据对象的实际类型来调用相应的函数,从而实现了不同类型的动物发出不同的声音。这种灵活性和可扩展性使得我们能够轻松地添加新的派生类,并在不改变现有代码的情况下扩展程序的功能 , 使得程序能够根据对象的实际类型来调用相应的函数。这种灵活性和可扩展性使得代码更具有适应性和可维护性。

相关文章:

  • Kubernetes里的DNS;API资源对象ingress;Kubernetes调度;节点选择器NodeSelector;节点亲和性NodeAffinity
  • 五:爬虫-数据解析之xpath解析
  • 【C++】简单工厂模式
  • C++STL的string(超详解)
  • 大量 SVG 图标在 React 中的极速集成与应用
  • MySQL概述-安装与启动
  • P1317 低洼地题解
  • 【Flutter】vs2022上开发flutter
  • 免费的SEO外链发布工具,提升排名的利器
  • 63. 不同路径 II
  • 二叉搜索树中第K小的元素[中等]
  • unittest与pytest的区别
  • 【已解决】解决UbuntuKali无法进行SSH远程连接
  • 理解基于 Hadoop 生态的大数据技术架构
  • k8s 安装部署
  • [译]CSS 居中(Center)方法大合集
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • CentOS从零开始部署Nodejs项目
  • flutter的key在widget list的作用以及必要性
  • happypack两次报错的问题
  • isset在php5.6-和php7.0+的一些差异
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Java 内存分配及垃圾回收机制初探
  • Javascript编码规范
  • java中具有继承关系的类及其对象初始化顺序
  • node入门
  • Redis学习笔记 - pipline(流水线、管道)
  • text-decoration与color属性
  • vue.js框架原理浅析
  • 深入 Nginx 之配置篇
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 一份游戏开发学习路线
  • 选择阿里云数据库HBase版十大理由
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ‌JavaScript 数据类型转换
  • #Datawhale AI夏令营第4期#多模态大模型复盘
  • (1)bark-ml
  • (k8s)kubernetes 部署Promehteus学习之路
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (苍穹外卖)day03菜品管理
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (三)mysql_MYSQL(三)
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .“空心村”成因分析及解决对策122344
  • .CSS-hover 的解释
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .NET企业级应用架构设计系列之结尾篇
  • /bin、/sbin、/usr/bin、/usr/sbin
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [20161101]rman备份与数据文件变化7.txt