C++虚函数

C++——虚函数 虚函数表(VTable):用来存储类中所有虚函数的地址。虚函数指针(VPtr):实例化对象指向所属类虚函数表的指针。通过基类指针调用虚函数:程序会通过基类指针获取对象的VPtr,进而找到对应类的虚函数表中相应的条目,调用正确的虚函数实现。纯虚函数:虚函数的一种特殊形式,和普通虚函数不同,它只在类中声明但不具体实现,迫使派生类重写该虚函数并提供具体实现。抽象类:包含至少一种纯虚函数的类,不能实例化对象,只能作为基类被其他类继承。 阅读详情

纯虚函数

  • 纯虚函数
	virtual void fun() = 0;

纯虚函数的出现时为了应对一些特殊的情况,即基类无法实现某些抽线行为,交由继承类去实现。
=0告诉编译器此函数为纯虚函数,由此可以引出抽象类。
抽象类指的是包含一个或者一个以上的纯虚函数的类。
派生类继承基类的时候必须实现纯虚函数,否则编译不通过。

虚函数

  • 普通虚函数
	virtual void fun() {}

首先来说普通虚函数是如何实现多态,虚函数实现多态的主要思想是通过基类指针调用基类和派生类中同名、同参数表的虚函数语句,基类指针指向什么对象,运行时就调用哪个派生类的虚函数。

比如在继承Person类的Worker、Student类中都有睡觉这个功能,但是他们由于身份的不同,睡眠时间是不同的。

class Person {
public:
	Person() {
		cout << "Person 构造函数 " << endl;
	}
	void eat() {}//吃饭
	virtual void sleep() {
		cout << "人类睡8小时最佳..." << endl;
	}
	~Person() {
		cout << "Person 析构函数 " << endl;
	}
protected:
	int age; // 年龄
	int height; // 身高
};
class Worker : public Person {
public:
	Worker() {
		cout << "Worker 构造函数 " << endl;
	}
	virtual void sleep() {
		cout << "工人顶多睡7小时" << endl;
	}
	~Worker() {
		cout << "Worker 析构函数 " << endl;
	}
};
class Student : public Person {
public:
	Student() {
		cout << "Student 构造函数 " << endl;
	}
	virtual void sleep() {
		cout << "学生顶多睡6小时" << endl;
	}
	~Student() {
		cout << "Student 析构函数 " << endl;
	}
};
 
void main(void)
{ 
	Worker w;   // 1
	Student s;   // 2
	Person *p = &w;    // 3
	p->sleep();  //4
	p = &s;
	p->sleep();
}

虚函数运行结果
1-4行:由于Worker和Student继承自Person,所以二者在使用类名对象名创建对象时,都会首先调用Person构造函数,再调用自己的构造函数。
**5-6行:**首先将Worker对象w拷贝给Person基类的指针p,并调用sleep方法。由于sleep方法申明为虚函数,所以基类指针p根据对象w去调用w的sleep方法,输出工人睡觉的时间!Student的对象同理
7-10行:由于使用类名对象名创建对象,所以在结束时会自动调用彼此的析构函数。析构函数的调用顺序和构造函数相关,最先调用构造函数的最后析构。

面试问题

问题一、那么哪些函数不可以申明为虚函数呢?

  1. 构造函数
    首先虚函数的调用需要通过查虚函数表,但是虚函数表需要在构造函数创建实例以后才生成。如果构造函数是虚函数,则无法创建实例,类的成员也不可被访问。
  2. 静态函数
    静态函数属于整个类,不属于任何一个类的对象。本身就是实体,不可被定义为虚函数。
  3. 非成员函数
    非成员函数不属于类,所以无法生成虚函数表。虚函数必须要求是成员函数。
  4. 友元函数
    友元函数定义在类外,虽然有权访问类的private和protected成员,但是友元函数并非成员函数。
  5. 内联成员函数
    内联成员函数在编译时就需要展开,而虚函数在执行时才可动态绑定,所以不适用。

问题二、为什么使用类名对象名创建对象会自动调用析构函数?

面试官经常喜欢问的问题有两个

  1. 类名对象创建对象和使用new创建对象有何区别?
  2. 基类析构函数为何必须定义为虚函数?

问题1:
类名对象创建对象

	Person p;

这种方式是在局部栈区创建对象,栈区随着程序的结束栈区会自动释放,所以对象会自动调用析构函数。这种方式创建对象速度快,毕竟是在栈区,比较适合频繁创建对象和对象比较小的应用场景。
new 创建对象

	Person* p = new Person();
	delete p;

这种创建方式在堆上创建对象,程序结束是不会对堆内存进行释放的,对应的程序中应该手动对其进行释放内存。new一般与delete配合使用。

问题2:
基类析构函数设置为虚函数是为了防止内存泄漏的情况。如果使用类名对象在栈区创建对象的方式,这是没任何问题的。因为栈区会在程序结束时候自动释放栈区内存,自动调用析构函数。
但是如果使用new方式创建对象,可能造成在delete释放的时候发生问题。当然也分为两种情况:

  1. delete 释放的指针是派生类的指针
//	接着上文的代码,修改main函数中对象创建的方式
class Person {
public:
	Person() {
		cout << "Person 构造函数 " << endl;
	}
	virtual void sleep() {
		cout << "人类睡8小时最佳..." << endl;
	}
	~Person() {   //  基类析构函数非虚函数
		cout << "Person 析构函数 " << endl;
	}
protected:
	int age; // 年龄
	int height; // 身高
};
void main(void)
{
	Worker* w = new Worker();
	Person *p = w;
	p->sleep();
	delete w;
}

从执行结果可以看出,如果delete释放的是派生类指针,基类和派生类都会调用析构函数,不存在内存泄漏的情况。
在这里插入图片描述
2. delete 释放的指针是派生类的指针

void main(void)
{
	Worker* w = new Worker();
	Person *p = w;
	p->sleep();
	delete p;
}

从执行结果可以看出,派生类并没有调用析构,这时产生内粗泄漏。
在这里插入图片描述
如果将基类析构函数定义为虚函数,无论delete基类指针还是派生类指针都会自动调用所有析构函数,解决内存泄漏问题

数字孪生模型构建理论及应用 源自:计算机集成制造系统作者:陶飞 张贺 戚庆林 徐 俊 孙铮 胡天亮 刘晓军 刘庭煜 关俊涛 陈畅宇 孟凡伟 张辰源 李志远 魏永利 朱铭浩 肖斌数字孪生作为实现数字化转型和促进智能化升级的重要使能途径,一直备受各行各业关注,已从理论研究走向了实际应用阶段。数字孪生是以多维虚拟模型和融合数据双驱动,通过虚实闭环交互,来实现监控、仿真、预测、优化等实际功能服务和应用需求,其中数字孪生模型构建是实现数字孪生落地应用的前提。 阅读详情

相关推荐

抖音私信卡片私信名片的原理分析

简单说一下它的功能吧:抖音私信卡片,解决了客户封号严重、引流效率低的痛点,所以从去年到现在,依然是热销品。"抖音快手私信名片链接跳转"是2022年抖音快手引流最新技术,可以生成卡片链接,支持标题、描述、logo以及跳转落地页的完全自定义配置.支持微信公众号和微信号复制唤起微信客户端app添加,同时也支持任意链接落地页跳转提高粉丝引流转化率,关注转化率,引流转化率,安全绿色私信卡片功能1、跳转微信用户点击卡片,自动跳转微信界面,显示好友和群聊二维码2、跳转链接用户点击卡片,自动跳转到指定链接,支持任意链接。3

m0_71385839的博客 5189

纯虚函数virtual void fun()=0;抽象类不能实例化对象

class Animal { public: virtual void fun()=0;// =0 就是纯虚函数,也叫抽象函数 } 包含有纯虚函数(抽象函数)的类叫抽象类。(哪怕类里面只有一个抽象函数那也是抽象类); 抽象类不能实例化; 子类继承抽象类(该抽象类是父类),除非将父类中的全部抽象函数都实现,否则子类依然是抽象类,依然不能实例化对象。(原因:子类继承父类的抽象函数,如果有一个没实现,那对于子类而言就是包含抽象函数的类,所以当然还是抽象类) 换言之:如果定义了一个.

明月清风 精进不止 2755

【OpenVINO】OpenVINO C# API 常用 API 详解与演示

在本文中我们基于模型推理流程,演示了OpenVINO C# API使用方法,并和OpenVINO C++API进行了对比,展示了OpenVINO C# API与C++API在使用的区别,这也对使用过C++ API的开发者十分友好,上手会十分容易。在本文中我们只展示了基础的模型推理流程代码,也对各个API进行了测试,针对其他比较高级的API方法,我们后续会继续进行测试其他API方法,向各位开发者展示其用法。

grape_yan的博客 1539

C++中的虚函数(virtual function)

C++中的虚函数(virtual function) 1.简介 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次:class A{public:virtual void foo() { cout "A::foo() is called" endl;}};class B: public A{public:virtual

DX 2843

从波形到代码:手把手调试GaN图腾柱PFC的过零点切换与软启动策略

本文详细解析了GaN图腾柱无桥Boost PFC电路在过零点切换与软启动策略中的调试方法。通过波形分析、代码实现和寄存器配置,提供了解决误开通、震荡波形等问题的实用方案,帮助工程师优化电源设计效率与可靠性。

weixin_30831529的博客 424

Win11显卡驱动安装失败的全面解决方案

Windows 11显卡驱动安装失败是一个比较常见的问题,但通过上述方法,我们可以有效地解决这一问题。方法一通过调整组策略编辑器的驱动程序安装策略,可能解决一些因签名问题导致的安装失败;而方法二则通过重装Windows 11系统,为系统提供一个全新的、干净的环境,从而可能解决更复杂的安装问题。在实际操作中,用户可以根据具体情况选择合适的方法来解决显卡驱动安装失败的问题。

nntxthml的博客 2662

虚函数和纯虚函数的区别

首先:强调一个概念定义一个函数为虚函数,不代表函数为不被实现的函数。 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数,才代表函数没有被实现。 定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。1、简介 假设我们有下面的类层次:class A { public: virtual void foo() { c...

编程资料大全 4898

Unity 工具 之 ZXing QRCode 二维码的生成和识别(可设置生成不同颜色的/带图标的二维码)

Unity 基础 之 ZXing QRCode 二维码的生成和识别(可设置生成不同颜色的/带图标的二维码) 目录 Unity 基础 之 ZXing QRCode 二维码的生成和识别(可设置生成不同颜色的/带图标的二维码) 一、简单介绍 二、实现原理 三、注意实现 四、效果预览 五、ZXing.net ( zxing.unity.dll ) 插件下载 六、实现步骤 七、关键代码 一、简单介绍 Unity 开发中,自己整理的一些游戏开发可能用到的功能,整理归档,方便游...

仙魁XAN 9825

C++ 纯虚函数 virtual = 0

纯虚函数 virtual = 0

心中天堂的专栏 751

Multisim14使用教程详尽版--(2025最新版)

摘要:本文详细介绍了Multisim14电路仿真软件的功能和使用方法。主要内容包括:1)主流电路仿真软件比较,突出Multisim在教学、竞赛设计中的优势;2)软件界面说明,涵盖菜单栏、工具栏、元器件库和仪器仪表;3)18类元器件分类详解及其使用操作;4)15种仪器仪表的原理和应用场景;5)电路原理图设计与仿真流程;6)基本电路分析方法(直流静态工作点分析、交流分析等)。文章还提供了硬件工程师笔试面试相关资源链接,涵盖电阻、电容、三极管等器件知识及AD软件操作指南。通过系统讲解,帮助用户掌握Multisim

XU157303764的博客 2万+

uniapp [全端兼容] - 实现接入集成高德地图搜索地址及选择位置功能,搜索框检索选择地点并返回经纬度及详细省市区县街道地址,用户搜索历史及清空历史记录,选择地址自动获取周边位置列表/地图移动选点

uni-app,高德地图,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,Uniapp高德地图,在地图上选择或搜索指定地点,打开地图选择位置,关联地址搜索,输入地址返回附近地址列表,uniApp高德地图地址搜索,搜索框历史记录,关键字搜索,周边查询,搜索位置,uniapp对接高德实现搜索出现地址以及保存搜索记录,集成高德地图,实现精准位置选点功能,获取当前定位城市,如何实现搜索功能,获取省份城市区街道详细地址经纬度,移动选点标记位置,在地图上进行选择位置选点、搜索

🏆 前端领域优质创作者 1万+

【C++】cpp虚函数和纯虚函数的声明和定义

摘要:C++中的虚函数和纯虚函数是实现多态的核心机制。虚函数通过virtual关键字声明,提供默认实现,派生类可选择性重写;纯虚函数通过=0声明,强制派生类实现,使基类成为抽象类。虚函数支持运行时多态,纯虚函数用于定义接口。两者关键区别在于:虚函数必须有定义且基类可实例化,纯虚函数无定义且基类不可实例化。使用时需注意析构函数应为虚函数,重写建议使用override关键字,以及纯虚函数可提供默认实现等特性。

Ape's IT Blog 982

SAR图像去斑(Despeckling)研究的主流开源数据集

这些数据集专门用于训练监督学习去斑模型,提供了配对的含斑SAR图像和对应的无噪声参考图像(Ground Truth)。这些数据集主要用于目标检测/识别,但包含原始SAR图像,可用于。由于缺乏真实无噪声SAR图像,许多研究采用。

VectorShift的博客 130

虚函数,纯虚函数,抽象类,点H与点CPP文件的结合

虚函数,纯虚函数,抽象类,经典例题,点H与点CPP文件的结合,声明与定义

LingXi__Y的博客 1777

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++虚函数详解

C++虚函数详解 前言 C++的特性使得我们可以使用函数继承的方法快速实现开发,而为了满足多态与泛型编程这一性质,C++允许用户使用虚函数**(virtual function)来完成运行时决议这一操作,这与一般的编译时决定**有着本质的区别。 虚函数表实现原理 虚函数的实现是由两个部分组成的,虚函数指针与虚函数表。 虚函数指针 虚函数指针**(virtual function pointer)*...

Whitesad的博客 12万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【C++】深入理解C++虚函数与纯虚函数

虚函数是在基类中使用关键字virtual声明的成员函数,它允许派生类对其进行重写(Override),实现运行时多态。当通过基类指针或引用调用虚函数时,实际调用的是对象类型对应的派生类中的函数,这个过程称为动态绑定(Dynamic Binding)或晚绑定(Late Binding)。虚函数重写指的是派生类中提供一个函数版本,该版本与基类中具有相同名称、相同返回类型和相同参数列表的虚函数相匹配。通过这种方式,派生类可以提供自己特定的实现,替换或扩展基类的行为。

Colorful___的博客 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Cpp-虚函数

虚函数,虚析构函数,纯虚函数,抽象类 虚函数 定义:在函数前加virtual,例子void virtual demo(); 作用:多态的重要部分 一般来说父类中的函数被子类函数重写必须采用虚函数。 class Shape { public: virtual double calcArea(){...}//虚函数 ....

Cutepingping的博客 3250

[cpp进阶]多态和虚函数

文章目录多态的概念 多态的概念 多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 比如说: 买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票。 买票这一个行为,不同的人做就有不同的行为和结果,这就是多态。 ...

weixin_53027918的博客 1245

cpp的虚函数详解

虚函数是为了实现运行时多态(runtime polymorphism),这样能够实现基类指针调用子类对象的方法。

不要被失望的瞬间击败 669

CPP多态性与虚函数

文章目录多态性与虚函数面向对象程序设计中的多态性派生类与基类对象之间的赋值虚函数虚析构函数纯虚函数(抽象类)虚函数与虚基类派生类中重定义基类中的重载函数虚函数动态绑定的实现原理 多态性与虚函数 面向对象程序设计中的多态性 多态性(polymorphism) 调用同一个函数名,根据需要实现不同的功能。 编译时的多态性:静态多态(函数重载、运算符重载) 运行时的多态性:动态多态(虚函数) 函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时就能决定调用的是哪个函数。静态多态性又称编译时的多态性。静态

SongyangJi 1589

cpp_11_虚函数_多态_纯虚函数

虚函数(虚方法) 虚函数的主要应用(动态多态) 纯虚函数

wwwwood的博客 1267

C++ 虚函数详解

前言 C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。 关于虚函数的使用方法,我在这里不...

smartDMer的专栏 7871

C++ 虚函数和纯虚函数

虚函数和纯虚函数的区别 首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数。 定义它为虚函数是 为了允许用基类的指针来调用子类的这个函数 , 也就是 虚函数是指一个类中你希望重载的成员函数 ,当你用一个 基类指针或引用 指向一个子类对象的时候,调用一个虚函数时, 实际调用的是子类的版本。 定义一个函数为纯虚函数,才代表函数没有被实现。 定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。 一、虚函数 1.虚函数定义 在基类中实现虚函

qq_39779233的博客 4185

cpp虚函数

cpp虚函数及多态的介绍

qq_42752524的博客 423

C++ 纯虚函数 虚函数 override

override在C++中它是覆盖了一个方法并且对其重写,从而达到不同的作用。在我们C++编程过程中,最熟悉的就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。还有一个典型应用就是在继承中也可能会在子类覆盖父类的方法。 1.公有继承 包含两部分:一是“接口”(interface),二是 “实现” (implementation)。 class Shape { public: virtual void Draw() const = 0;

软件工程小施同学 的专栏 3894

Cherno的Cpp教程笔记011:C++继承+虚函数

private,

ResumeProject的博客 281
上一篇: C++单例模式实现
下一篇: C++11多线程模拟售票
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值