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

【学习笔记】虚函数+虚析构函数

【学习笔记】虚函数+虚析构函数

1、虚函数

虚函数是类中使用 virtual 关键字声明的成员函数,它允许子类(派生类)重新定义(覆盖)该函数,从而在运行时根据对象的实际类型动态决定调用哪个版本的函数。

多态性是面向对象编程的三大特性之一(封装、继承、多态),指的是同一函数调用可以根据对象类型的不同,执行不同的操作。

class Base {public:Base();virtual ~Base();..........virtual int UpdataIP(MIO_JSON* pJson);
}int Base::UpdataIP(MIO_JSON* pJson) 
{return 0;
}

Base 类中有一个虚函数 UpdataIP,但是在这个类中这个虚函数并没有实际意义。但是Hahanode以及Hehenode继承了这个类,在这两个继承类中分别对这个函数做了不一样的操作。

class HahaNode : public Base {public:HahaNode();~HahaNode();int UpdataIP(MIO_JSON* pJson);
..........
}int HahaNode::UpdataIP(MIO_JSON* pJson) 
{// 实际操作
}class HeheNode : public Base {public:HeheNode();~HeheNode();int UpdataIP(MIO_JSON* pJson);
..........
}int HeheNode::UpdataIP(MIO_JSON* pJson) 
{// 实际操作
}

2、虚析构函数

​ 为什么一般将析构函数设置为虚函数。

​ 防止内存泄漏:当基类析构函数不是虚函数时,要是通过基类指针删除派生类对象,系统只会调用基类的析构函数,而不会调用派生类的析构函数。这就可能使派生类特有的资源(像动态分配的内存、文件句柄、网络连接等)无法被释放,进而造成内存泄漏。

虚析构函数的作用:把析构函数声明为虚函数之后,在运行时会依据对象的实际类型来决定调用哪个析构函数,而不是根据指针的静态类型。这样一来,当通过基类指针删除派生类对象时,派生类的析构函数会先被调用,接着基类的析构函数也会被调用,从而确保所有资源都能被正确释放。

#include <iostream>class Base {
public:Base() { std::cout << "Base Constructor" << std::endl; }// 若不声明为虚函数,可能会引发问题virtual ~Base() { std::cout << "Base Destructor" << std::endl; }
};class Derived : public Base {
private:int* data;
public:Derived() {std::cout << "Derived Constructor" << std::endl;data = new int[100]; // 动态分配内存}~Derived() override {std::cout << "Derived Destructor" << std::endl;delete[] data; // 释放派生类资源}
};int main() {Base* ptr = new Derived(); // 基类指针指向派生类对象delete ptr; // 调用虚析构函数,确保资源正确释放return 0;
}

结果:

Base Constructor        //创建基类构造函数
Derived Constructor     //创建派生类构造函数
Derived Destructor      //删除派生类析构函数
Base Destructor         //删除基类析构函数

如果基类析构函数不是虚函数,那么delete ptr只会调用Base::~Base(),派生类的析构函数不会被调用,data所占用的内存就无法被释放。

http://www.xdnf.cn/news/13241.html

相关文章:

  • 半导体设备基本通信标准介绍
  • shell脚本拔高习题
  • Word-- 制作论文三线表
  • SQL SERVER 数据库迁移的三种方法!
  • git clone 时报错超时的问题解决方案
  • 人工智能驱动的企业变革:从智能辅助到战略赋能
  • 【C#】C++的回调函数和C#的事件委托在某些方面有相似之处
  • 前端6月份之前的部分技术更新记录
  • mongDB
  • CentOS7.9 查询运维安全日志,排查恶意用户
  • 用C#实现单向链表和双向链表
  • 《滑动窗口》题集
  • 基于KubeSphere平台快速搭建单节点向量数据库Milvus
  • 【React-router-dom】浅拷贝,查询参数放到路由上
  • vue的这两个特性:数据驱动视图 与 双向数据绑定的区别
  • 工业环境的首选:试验台铁底板稳定性
  • 从设备监控到人员调度,可视化赋能车间全场景
  • 搭建一个springColud 项目,从头开始,里面有订单,库存两个模块
  • LangChain Chat History概念指南
  • 【ModelArts】ModelArts一站式AI开发平台详解(一)
  • 【WiFi扫描相关帧】
  • 条码二维码如何在数字医疗守护安全与效率?
  • 日志收集工具-logstash
  • Echarts大量数据柱图,禁止滑块拖动宽度,以及适配分辨率。
  • CentOS7下的Kafka集群安装部署
  • MongleDB数据库应用
  • 【Flash 芯片 MTD 专栏】Flash芯片识别异常导致mtd子系统分区创建失败
  • 如何判断一个bug,是前端还是后端的?
  • 工作记录:人物对话功能开发与集成
  • linux thermal framework(1)_概述