C++中的虚函数:深入探究多态性

news2024/9/9 5:50:47

目录

​编辑

引言

虚函数基础

纯虚函数与抽象类

虚函数与多态

虚析构函数

结论


引言

在C++中,虚函数是实现多态性的关键机制,它允许我们编写更为灵活和可扩展的代码。通过虚函数,派生类可以提供不同的实现,而基类指针或引用可以调用这些派生类的实现,这就是所谓的运行时多态。本文将详细介绍虚函数的使用、意义以及一些高级主题,如纯虚函数和抽象类,同时辅以丰富的代码示例和注释。

虚函数基础

虚函数的基本概念是,一个类中的成员函数可以被其派生类重写。要声明一个虚函数,只需在函数声明前加上virtual关键字。这里是一个简单的示例:

#include <iostream>

// 声明基类 Shape
class Shape {
public:
    // 声明虚函数 draw()
    virtual void draw() {
        std::cout << "Drawing a generic shape." << std::endl;
    }
};

// 声明派生类 Circle
class Circle : public Shape {
public:
    // 重写虚函数 draw()
    void draw() override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

int main() {
    Shape* shapePtr = new Circle(); // Shape指针指向Circle对象
    shapePtr->draw();               // 调用Circle::draw()

    delete shapePtr;                // 释放内存
    return 0;
}
纯虚函数与抽象类

纯虚函数是一个没有实现的虚函数,它在基类中声明,但在基类中不提供实现。这样的函数以= 0结尾,使得任何包含纯虚函数的类都变成了抽象类,抽象类不能被实例化。

class AbstractShape {
public:
    // 声明纯虚函数 draw()
    virtual void draw() = 0;
};

// 这是一个错误,因为AbstractShape是抽象类,不能实例化
// AbstractShape as;

// 正确的使用方式:定义一个派生类并实现纯虚函数
class ConcreteShape : public AbstractShape {
public:
    void draw() override {
        std::cout << "Drawing a concrete shape." << std::endl;
    }
};
虚函数与多态

虚函数的真正威力在于多态性,即一个接口可以有多种实现。以下代码展示了如何通过基类指针调用派生类的不同实现:

class Animal {
public:
    virtual void makeSound() {
        std::cout << "The animal makes a sound." << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Woof woof!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Meow meow!" << std::endl;
    }
};

void makeAllAnimalsSound(Animal* animal) {
    animal->makeSound();
}

int main() {
    Animal* dog = new Dog();
    Animal* cat = new Cat();

    makeAllAnimalsSound(dog); // 输出: Woof woof!
    makeAllAnimalsSound(cat); // 输出: Meow meow!

    delete dog;
    delete cat;

    return 0;
}
虚析构函数

在使用虚函数时,通常会将基类的析构函数声明为虚函数。这可以确保当通过基类指针删除派生类对象时,正确的析构函数会被调用。

class Base {
public:
    virtual ~Base() {} // 虚析构函数
};

class Derived : public Base {
public:
    ~Derived() {
        std::cout << "Derived destructor called." << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    delete basePtr; // 调用Derived的析构函数

    return 0;
}
结论

虚函数是C++中实现多态性的基石,它们使得代码更具灵活性和可扩展性。通过使用虚函数,我们可以设计出更加模块化和易于维护的软件架构。在实际项目中,理解并正确使用虚函数、纯虚函数以及虚析构函数是至关重要的。


本文通过一系列代码示例详细阐述了C++中虚函数的使用,包括基本概念、纯虚函数、抽象类以及多态性的实现。通过实践这些示例,你将能够更深刻地理解虚函数在C++中的作用和重要性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1918647.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面对频繁紧急修复,测试人员5大应对技巧!

频繁的紧急修复问题&#xff0c;经常会过多占用测试时间&#xff0c;影响正常测试周期和回归测试的完整性&#xff0c;不利于测试效率和质量的提高。因此为了更高效地处理此问题&#xff0c;测试人员可以采取以下5大策略来应对&#xff0c;以减少此类问题的发生并提高工作效率。…

王老师 linux c++ 通信架构 笔记(二)配置服务器为固定的 ip 地址、远程登录、安装 gcc g++ 与虚拟机文件夹共享

&#xff08;7&#xff09;本条目开始配置 linux 的固定 ip 地址&#xff0c;以作为服务器使用&#xff1a; 首先解释 linux 的网口编号&#xff1a; linux 命令 cd &#xff1a; change directory 改变目录。 ls &#xff1a; list 列出某目录下的文件 根目录文件名 / etc &a…

链接服务器“XX”的OLEDB访问接口“MSOLEDBSQL”返回了消息“登录超时已过期” 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 出现如下问题: 与链接服务器的测试连接失败。执行Transact-SQL 语句或批处理时发生了异常。命名管道提供程序:无法打开与SQL SERVER的链接[53]链接服务器“XX”的OLEDB访问接口“MSOLEDBSQL”返回了消息“登录超时已过期…

CV06_Canny边缘检测算法和python实现

1.1简介 Canny边缘检测算法是计算机视觉和图像处理领域中一种广泛应用的边缘检测技术&#xff0c;由约翰F坎尼&#xff08;John F. Canny&#xff09;于1986年提出。它是基于多级处理的边缘检测方法&#xff0c;旨在实现以下三个优化目标&#xff1a; 好的检测&#xff1a;尽…

如何录制屏幕视频?4款软件,轻松录屏

在数字化飞速发展的时代&#xff0c;如何录制屏幕视频已经成为我们工作、学习和娱乐中不可省略的一个重要问题。无论是制作教学教程还是录制游戏视频等&#xff0c;屏幕视频录制都为我们提供了极大的便利。今天&#xff0c;就让我们一起探索如何录制屏幕视频的精彩方式&#xf…

记录文字视差背景学习

效果图 文字背景会随鼠标上下移动变成红色或透明 html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…

Hydra

Intro Hydra是一个用来动态创建配置的python开源框架&#xff0c;使做研究和复杂的应用更便利&#xff0c;配置信息可以通过配置文件或者运行参数来覆盖。Hydra的名字来源于其可以运行多个相似任务&#xff0c;就像Hydra&#xff08;九头蛇&#xff09;有多个头一样。 Run 安…

初学51单片机之UART串口通信

CSDN其他博主的博文&#xff08;自用&#xff09;嵌入式学习笔记9-51单片机UART串口通信_51uart串口通讯-CSDN博客 CSDN其他博主的博文写的蛮好&#xff0c;如果你想了解51单片机UART串口可以点进去看看&#xff1a; UART全称Universal Asynchronous Receiver/Transmitter即通…

agents 分类

一、分类 自动agent、半自动agent、领域、自定义sop和支持人为干预的agent。 先泼个冷水&#xff0c;目前这些agent项目都是实验品&#xff0c;发展还没有做知识库问答相关开源项目那么成熟&#xff0c; 二、全自动agent autoGPT、loopGPT、babyAGI 全自动agent就是人类不可…

设计模式8-桥模式

设计模式8-Bridge 桥模式 由来与目的模式定义结构代码推导1. 类和接口的定义2. 平台实现3. 业务抽象4. 使用示例总结1. 类数量过多&#xff0c;复杂度高2. 代码重复3. 不符合单一职责原则4. 缺乏扩展性改进后的设计1. 抽象和实现分离&#xff08;桥接模式&#xff09;2. 抽象类…

Python爬虫:BeautifulSoup的基本使用方法!

1.简介 Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析“标签树”等功能。它是一个工具箱&#xff0c;通过解析文档为用户提供需要抓取的数据&#xff0c;因为简单&#xff0c;所以不需要多少代码就可以写出一个完整的应用程序。 Beautiful Soup…

一款面向程序员群体的AI问答产品火了!主打专业、正确率保障,消灭AI回答不可靠的问题

一直以来&#xff0c;无论是GPT、Claude还有国内的AI对话产品&#xff0c;都一直被诟病“AI回答不可靠”&#xff0c;尤其是在程序员这类对AI回答的可靠性要求极高的场景&#xff08;毕竟AI给代码里埋个bug&#xff0c;背锅的还是程序员&#xff09;。 而且当AI给的代码不可靠…

Androd 12 (MTK)修改屏幕物理分辨率Physical Size

1.需求说明 Android目前显示分辨率为480*800&#xff0c;立项表中像素为720*1280。请修改屏幕分辨率到指定大小。 2.思路分析 如果从手机修改对应的分辨率&#xff0c;必须自上而下的进行修改分为两个层面进行修改。 1.驱动底层 2.软件上层 3.结局方法与相关说明 查看当…

Vue打包文件dist放在SpringBoot项目下运行(正确实现全过程)(下)

在上一篇中&#xff0c;实现了Vue打包文件dist放在SpringBoot项目下运行。 Vue打包文件dist放在SpringBoot项目下运行&#xff08;正确实现全过程&#xff09;&#xff08;上&#xff09; 问题 路由刷新会产生404的问题。 原因 vue开发的应用&#xff0c;采用的是SPA单页…

c语言的简易教法—— 函数递归

文章目录 一、什么是递归&#xff1f;1.1递归的思想1.2递归的限制条件 二、递归案例2.1 案例1&#xff1a;求n的阶层2.1.1分析2.1.2 递归函数&#xff08;Fact&#xff09;的代码实现2.1.3 测试&#xff1a;main函数实现2.1.4 运行结果和画图推演2.1.5 扩展&#xff1a;迭代方法…

纹波电流与ESR:解析电容器重要参数与应用挑战

电解电容纹波电流与ESR&#xff08;Equivalent Series Resistance&#xff09;是电容器的重要参数&#xff0c;用来描述电容器对交流信号的响应能力和能量损耗。电解电容纹波电流是指电容器在工作时承受的交流信号电流&#xff0c;而ESR则是电容器内部等效电阻&#xff0c;影响…

2024年PMP报考需要什么条件?怎么报名?

PMP报名条件要求不高&#xff0c;只要满足下面两个条件&#xff1a; 1、35个PDU &#xff08;需要有 PMI 授权的机构颁发&#xff09; 2、项目经验 学士学位需要 4500 个小时的项目管理经验&#xff0c;3年工作经验&#xff1b; 非学士学位需要 7500 个小时的 项目管理经验&…

机器视觉:(1) 初识Roboflow(使用详解一)获取数据集(最新)

一&#xff1a;访问地址 [1] Roboflow官网&#xff1a;官网地址 [2]YOLOv8 项目地址github源码地址 [3]YOLOv8 官方教程官网教程地址 二&#xff1a;获取数据集步骤 1.访问官网地址&#xff1a;进入首页面&#xff0c;点击登录 2.注册过程省略了&#xff0c;按步骤走就可以…

Qt:18.状态栏(状态栏介绍、代码方式创建状态栏、在状态栏显示临时信息、在状态栏创建控件)

目录 1.状态栏介绍&#xff1a; 2.代码方式创建状态栏&#xff1a; 3. 在状态栏显示临时信息&#xff1a; 4.在状态栏创建控件&#xff1a; 1.状态栏介绍&#xff1a; Qt 状态栏是 QMainWindow 窗口的一部分&#xff0c;通常用于显示临时信息&#xff0c;如应用程序的状态、…

myeclipse开发ssm框架项目图书管理系统 mysql数据库web计算机毕业设计项目

摘 要 随着计算机的广泛应用&#xff0c;其逐步成为现代化的标志。图书馆的信息量也会越来越大&#xff0c;因此需要对图书信息、借书信息、还书信息等进行管理&#xff0c;及时了解各个环节中信息的变更&#xff0c;要对因此而产生的单据进行及时的处理&#xff0c;为了提高高…