【C++】关于虚函数的理解

深入探索C++虚函数:原理、应用与实例分析

  • 一、虚函数的原理
  • 二、虚函数的应用
  • 三、代码实例分析
  • 四、总结

在这里插入图片描述

在C++面向对象编程的世界里,虚函数(Virtual Function)扮演着至关重要的角色。它不仅实现了多态性这一核心特性,还使得代码更加灵活、可扩展。本文将详细探讨C++虚函数的原理、应用,并通过具体的代码实例进行说明解释。

一、虚函数的原理

虚函数是C++中用于实现动态多态性的一种机制。它允许在派生类中对基类中的虚函数进行重写(Override),从而在运行时根据对象的实际类型来确定调用哪个版本的函数。这种机制使得程序能够处理不同类型的对象,而无需了解这些对象的具体类型。
在C++中,通过在基类中将成员函数声明为virtual,即可将其定义为虚函数。例如:

cppclass Base {
public:virtual void foo() {std::cout << "Base::foo()" << std::endl;}
};class Derived : public Base {
public:void foo() override { // 使用override关键字确保重写成功std::cout << "Derived::foo()" << std::endl;}
};

在上面的代码中,基类Base中定义了一个虚函数foo(),派生类Derived通过重写foo()函数,提供了自己的实现。当通过基类指针或引用调用foo()函数时,会根据指针或引用所指向的对象的实际类型来确定调用哪个版本的函数。

二、虚函数的应用

虚函数在C++中的应用广泛,主要包括以下几个方面:
实现多态性:通过虚函数,我们可以在基类中定义通用的接口,然后在派生类中提供具体的实现。这样,我们就可以使用基类指针或引用来操作不同类型的对象,而无需关心这些对象的实际类型。
扩展功能:当需要为现有类添加新功能时,可以通过继承该类并添加新的虚函数来实现。这样,就可以在不修改原有代码的情况下,为现有类添加新的功能。
解耦:通过虚函数,我们可以将类的实现与接口分离,从而实现代码的解耦。这有助于降低代码的耦合度,提高代码的可维护性和可扩展性。

三、代码实例分析

下面是一个具体的代码实例,用于演示虚函数在C++中的应用:

cpp#include <iostream>
#include <vector>
#include <memory>// 基类:形状
class Shape {
public:virtual ~Shape() {} // 虚析构函数,确保正确释放派生类对象virtual void draw() const = 0; // 纯虚函数,作为接口virtual double area() const = 0; // 纯虚函数,作为接口
};// 派生类:圆形
class Circle : public Shape {double radius;
public:Circle(double r) : radius(r) {}void draw() const override {std::cout << "Drawing a circle with radius " << radius << std::endl;}double area() const override {return 3.14 * radius * radius;}
};// 派生类:矩形
class Rectangle : public Shape {double width, height;
public:Rectangle(double w, double h) : width(w), height(h) {}void draw() const override {std::cout << "Drawing a rectangle with width " << width << " and height " << height << std::endl;}double area() const override {return width * height;}
};
// 使用示例
int main() {std::vector<std::unique_ptr<Shape>> shapes; // 使用智能指针存储Shape对象的指针shapes.push_back(std::make_unique<Circle>(5.0));shapes.push_back(std::make_unique<Rectangle>(3.0, 4.0));// 遍历shapes,调用draw()和area()函数for (const auto& shape : shapes) {shape->draw();std::cout << "Area: " << shape->area() << std::endl;}return 0;
}

在上面的代码中,我们定义了一个基类Shape,它包含两个纯虚函数draw()和area(),作为接口。然后,我们定义了两个派生类Circle和Rectangle,分别实现了这两个纯虚函数。在main()函数中,我们使用了一个std::vector来存储指向Shape对象的智能指针。这些智能指针可以指向Circle或Rectangle类型的对象。通过遍历这个vector并调用draw()和area()函数,我们可以实现多态性:无需知道对象的实际类型,就可以调用它们的方法。

四、总结

虚函数是C++中实现多态性的关键机制之一。通过虚函数,我们可以将类的实现与接口分离,实现代码的解耦和扩展。在编写面向对象程序时,我们应该充分利用虚函数这一特性,提高代码的可维护性和可扩展性。同时,我们也需要注意虚函数的使用场景和性能开销,避免不必要的性能损失。

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

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

相关文章

查看linux服务器cpu,硬盘,内存

lscpu 查看cpu 释义 Architecture: x86_64 // 指定系统架构&#xff0c;这里是 x86_64&#xff0c;表示一个64位系统。 CPU op-mode(s): 32-bit, 64-bit // 指示支持的 CPU 操作模式&#xff0c;显示了32位和64位两种模式。 Byte Order: Little…

红酒与珠宝:璀璨与醇香的奢华交响,双重诱惑难挡

在璀璨的灯光下&#xff0c;红酒与珠宝各自闪耀着迷人的光芒&#xff0c;它们如同夜空中的繁星&#xff0c;交相辉映&#xff0c;共同演绎着奢华的双重诱惑。今天&#xff0c;就让我们一起走进这个充满魅力的世界&#xff0c;感受红酒与珠宝带来的无尽魅力。 首先&#xff0c;让…

java中自定义线程池最佳实践

java中自定义线程池最佳实践 在现代应用程序中&#xff0c;线程池是一种常用的技术&#xff0c;可以有效管理和复用线程资源&#xff0c;从而提升系统的并发性能和稳定性。本文将详细介绍自定义线程池的最佳实践&#xff0c;涵盖从线程池大小配置、队列选择到拒绝策略、任务设…

基于STM32+ESP8266打造智能家居温湿度监控系统(附源码接线图)

摘要: 本文将介绍如何使用STM32单片机、ESP8266 Wi-Fi模块和Python Flask框架构建一个完整的物联网系统&#xff0c;实现传感器数据采集、无线传输、云端存储及Web可视化展示。 关键词: STM32, ESP8266, 传感器, Flask, 物联网, 云平台, 数据可视化 1. 系统概述 本系统以STM…

Spring底层原理之proxyBeanMenthod实例 动态代理 反射 Bean的拦截

proxyBeanMenthod 假设我们要进行一个系统的二次开发 然后第一次开发我们实用的是XML声明bean 二次开发的时候要用注解 我们如何把bean都加载上来呢 我们首先创建一个全新的配置类 package com.bigdata1421.config;public class SpringConfig32 { } 我们创建一个APP 加载…

Perl语言入门学习读物

1. PERL 是什么? Perl 最初的设计者为Larry Wall&#xff0c;Perl借取了C、sed、awk、shell scripting以及很多其他程序语言的特性。Perl一般被称为“实用报表提取语言”(PracticalExtraction andReportLanguage)&#xff0c;有时也被称做“病态折中垃圾列表器”(Pathologica…

springboot+vue3无感知刷新token实战

目录 一、java后端 1、token构造实现类 ①验证码方式实现类 ②刷新token方式实现类 2、token相关操作&#xff1a;setCookie ①createToken ②refreshToken 二、前端&#xff08;vue3axios&#xff09; web网站中&#xff0c;前后端交互时&#xff0c;通常使用token机制…

全球最快的 JSON 文件查询工具

本文字数&#xff1a;1684&#xff1b;估计阅读时间&#xff1a;5分钟 审校&#xff1a;庄晓东&#xff08;魏庄&#xff09; 本文在公众号【ClickHouseInc】首发 介绍 在 ClickHouse&#xff0c;我们热衷于基准测试和性能优化。所以当我第一次看到 Hacker News 上那篇“查询大…

代码随想录算法训练营day31|134.加油站、135. 分发糖果、406.根据身高重建队列

134.加油站 如下图所示&#xff1a; 当索引一道2的时候&#xff0c;剩余油量的总量13-6 < 0&#xff0c;这个时候说明以索引0为起点不合适&#xff0c;将起点更新为索引3. 两点证明&#xff1a; 1.如果我们从蓝色段中间选一个点开始&#xff0c;是不是最后sumGas就不小于0…

从灵感到成品:使用AI生成博客文章的完整指南

在信息爆炸的时代&#xff0c;每个人都有讲述自己故事的权利和需求。博客作为一种表达方式&#xff0c;不仅能记录个人经历&#xff0c;还能分享知识和观点。然而&#xff0c;许多人在写博客文章时&#xff0c;常常会遇到灵感枯竭、时间不够用或者不知道如何开始等问题。幸运的…

光伏储能系统/安科瑞DTSD1352-CF双向计量表-安科瑞 蒋静

1 长期以来&#xff0c;我国施行居民用电低价政策&#xff0c;居民电价大幅低于供电成本&#xff0c;虽然实施了全天分三时段的阶梯电价政策&#xff0c;但过去近10年中高峰节电的效果却不够明显。从分时用电运作机制来看&#xff0c;居民用电价格的波动幅度不大&#xff0c;但…

华为云鲲鹏架构docker部署2048小游戏

华为云鲲鹏架构docker部署2048小游戏 1. 鲲鹏架构ESC2. 配置docker3. 上传2048镜像4. 删除容器,镜像 1. 鲲鹏架构ESC 2. 配置docker 安装dockeryum -y install docker开机启动 systemctl enable docker启动docker服务 systemctl start docker查询docker的运行版本 docker -v3…

时序分析基本概念介绍——min pulse width 最小脉冲宽度

文章目录 前言一、什么是 min pulse width&#xff1f;二、为什么检查 min pulse width&#xff1f;三、如何设置 min pulse width约束&#xff1f;1. 在sdc里面定义2. library里面定义 四、如何检查 min pulse width&#xff1f;五、如何修复 min pulse width&#xff1f;总结…

docker启动ws-scrcpy和redroid记录

git克隆最新的ws-scrcpy代码 git clone gitgithub.com:NetrisTV/ws-scrcpy.git进入ws-scrcpy目录新建Dockerfile文件&#xff0c;内容如下 FROM node:16-alpine WORKDIR /appRUN npm config set registry http://mirrors.cloud.tencent.com/npm/ RUN npm install -g node-gyp…

攻防世界-Web题目1

目录 cookie 1、题目 2、知识点 3、思路 get_post 1、题目 2、知识点 3、思路 disabled_button 1、题目 2、知识点 3、思路 backup 1、题目 2、知识点 3、思路 cookie 1、题目 2、知识点 cookie&#xff0c;数据包 3、思路 题目提示我们cookie&#xff0c;抓…

Markdown中如何插入空行和空格

Markdown 是一种轻量级的标记语言&#xff0c;它的主要目标是以易读易写为优先&#xff0c;并兼容 HTML。虽然 Markdown 本身对于排版的要求比较宽松&#xff0c;但在某些情况下&#xff0c;我们可能需要在文档中插入空行或空格来达到特定的排版效果。 插入空行 在Markdown中…

【ai】trition:tritonclient.utils.shared_memory 仅支持linux

Can’t find tritonclient.utils.shared_memory on WIN10 #4149yolov4的python客户端 导入以后,windows 的pycharm 就是看不到折腾了很久:SaviorEnv 环境下安装tritonclient[all]也会失败 (base) C:\Users\zhangbin>conda create -n SaviorEnv python=3.8 Collecting pack…

ubuntu 18 虚拟机安装(1)

ubuntu 18 虚拟机安装 ubuntu 18.04.6 Ubuntu 18.04.6 LTS (Bionic Beaver) https://releases.ubuntu.com/bionic/ 参考&#xff1a; 设置固定IP地址 https://blog.csdn.net/wowocpp/article/details/126160428 https://www.jianshu.com/p/1d133c0dec9d ubuntu-18.04.6-l…

元数据管理的发展历程你了解吗?元数据管理要克服哪些挑战?

在当今的信息化时代&#xff0c;数据的价值已被广泛认可&#xff0c;而元数据作为描述数据的数据&#xff0c;其作用日益凸显。元数据管理&#xff0c;作为确保数据质量、促进数据共享和提高数据透明度的关键环节&#xff0c;对企业的数据战略至关重要。随着技术的发展&#xf…

程序设计中对内存分配管理的思考,进程内存、线程内存、共享池、栈、堆

设计一个程序&#xff0c;要考虑如何分配和管理内存&#xff0c;以下是对所有内存分配和管理类型的总结。 第一、进程级的内存资源&#xff0c;也叫全局静态内存&#xff0c;其生命周期是伴随整个进程的运行期间&#xff0c;可以用作在进程范围内共享数据的方法。对应于C语言的…