虚函数学习2

C++学习——虚函数与纯虚函数 引言: 若要访问派生类中相同名字的函数,必须将基类中的同名函数定义为 虚函数,这样,将不同的派生类对象的地址赋给基类的指针变量后, 就可以动态地根据这种赋值语句调用不同类中的函数。 一、虚函数的定义和使用 可以在程序运行时通过调用相同的函数名而实现不同功能的 函数称为虚函数。定义格式为: virtual FuncName(); 一旦把基类的成员函数定义为虚函数,由基类所派生出来的所 有派生类中,... 阅读详情
#include <string>
#include <iostream>
using namespace std;

class Animal
{
public:
	virtual void print1()
	{
		cout << "Animal1" << endl;
	}
	virtual void print()
	{
		cout << "Animal" << endl;
	}
	int aaa1;
	int aaa2;
};
class Model
{
public:
	virtual void printM1()
	{
		cout << "Model1" << endl;
	}
	virtual void printM()
	{
		cout << "Model" << endl;
	}
	int bbb1;
};
class Normal1
{
	void printN()
	{
		cout << "Normal" << endl;
	}
};
class Normal2
{
public:
	void printN()
	{
		cout << "Normal" << endl;
	}
};
class Cat: public Model,public Animal,public Normal1,public Normal2
{
public:
	virtual void printM1()
	{
		cout << "CatModel1" << endl;
	}
	virtual void printM()
	{
		cout << "CatModel" << endl;
	}
	virtual void print1()
	{
		cout << "Cat1" << endl;
	}
	virtual void print()
	{
		cout << "Cat" << endl;
	}
};

void test(Animal* _pA)
{
	_pA->print();
}
void test1(Model* _pA)
{
	_pA->printM1();
}

int _tmain(int argc, _TCHAR* argv[])
{
	Animal* _pA = new Cat;
	Model* _pA1 = (Model*)_pA;  // ERROR
	Model* _pA2 = dynamic_cast< Cat* >(_pA);
	Model* _pA3 = (Cat*)_pA;
	test(_pA);
	test1(_pA1); // ERROR
	test1(_pA2);
	system("pause");
	return 0;
}



为何test(_pA)和test1(_pA2)能正确打印,test1(_pA1)却出错了,调用了print1函数?

通过_pA,_pA1等等指针的数值. 也可以看出编译器帮我们做的转换的细节. 

除了dynamic_cast是在运行时调用RTTI的机制向基类回溯查找,如果不能Cast就抛异常.其他的强转, 

其他都是编译器在编译期就进行指针数值的判定. 一般来说, 虚表指针__vfptr就在this的位置.

如果继承自多个虚基类,就会有多个虚表指针.分别是在代表被继承的类内存块的开始.

在强转的时候,编译器会根据前后的代码块来判定是否可以通过子类指针转到基类,

返回基类在子类中内存块的开始(虚表指针__vfptr地址), 如果不行,就只是指针数值的复制.

比如 Model* _pA1 = (Model*)_pA; 这句.转换的时候,就只是指针数值复制,导致_pA1调用printM就错了.其实调用了print1函数.

虽然字面上是Model*类型指针,实际还是Animal*的指针.


学习虚函数 用来修饰类的虚函数,使得该虚函数在子类中,不能被重写。如果基类指针指向的是基类对象,那么只调用。在项目属性中C/C++命令行选项中添加。override仅能用于修饰虚函数。用来修饰类,让该类不能被继承。,不需要在函数的实现中使用。,使基类析构函数为虚函数。释放基类指针时,会实现。理解:使得该功能终结。如果基类指针指向的是。 阅读详情

相关推荐

虚函数与多态性学习小结

   在C++中,多态有两种,一种是函数重载,一种是虚函数。函数重载发生在编译的时候,它的函数参数是不一样的。而虚函数是发生在运行的时候,它的函数原型是一样的,依靠的是指针的指向。结果似乎和我们想象的不一样,既然Graph类(图形类)的对象graph指针分别指向了Rectangle类(矩形类)对象,Triangle类(三角类)对象,以及Circle类(圆类)对象,那么就应该执行它们自己所对应成员函...

heyson20171784的博客 2601

【C++学习笔记】Step2 虚函数

目的:学习实函数、虚函数、纯虚函数,加例程演示 码云:https://gitee.com/hinzer/my-notes-of-C_plus 思维导图 学习笔记 1.C++父类指针&子类对象 <1>父类指针指向子类对象时,指针原型决定调用哪个函数 class People {//基类 private: int age; int sex; ...

本末实验室 896

Doris StreamLoad任务报错Connection reset

背景 Spark程序扫一张Hive表(大小3-7G),然后用http协议的streamLoad任务提交给Doris集群,在Doris集群从0.13.15升级到0.14.12后spark程序报错streamLoad时突然会Connection reset 分析 enable_http_server_v2 这个参数可以参考FE中文配置中查看到,作用是对于Doris界面是否开启新风格的界面,但是实际上他的作用远不止如此,请接着看 新老版本对于enable_http_server_v2参数默认值是不同的 在0.13

gaofeng的博客 3309

C++ Primier学习笔记2-虚函数

虚函数         多态(继承关系的多个类型)通过虚函数实现。         关键字virtual告诉编译器不应当完成早绑定,而是自动实现晚绑定/运行时绑定所必须的所有机制。动态绑定只有当通过指针或者引用调用虚函数时才会发生。         补充:析构函数可以是虚函数,所有的派生类的析构函数都将自动变为virtual型,不会出现由于析构函数未被调用而导致的内存泄漏(虚

cherry_hust的专栏 467

[华中科技计组实验]logisim完成单周期5级流水MIPS CPU

[华中科技计组实验]logisim完成单周期5级流水MIPS32 CPU hu~,终于完成了,真是费劲呐 支持24条指令,5级流水线,可以对分支指令处理,寄存器冲突处理,指令ROM为1K,数据RAM为1M,32位MIPS指令集CPU 但是… 大量使用比较器造成硬件开销巨大,测试一下发现这尼玛真是个老爷车还没单周期跑的快,自己电脑cpu占百分之八九十只能跑到20多赫兹,一个走马灯跑了半天,可优化空间太大了,写了那么多天造成这个破样,有点悲剧。。。 先放个图大伙参考就行了,要是有人想听思路的话接下来再更 .

zrc的博客 1万+

DataWorks数据安全治理最佳实践

DataWorks基于数据安全治理的常见思路,针对资产梳理、技术体系建设和运营体系建设,提供了一系列数据安全产品能力,您可通过“基础防护建设、数据安全防护措施及策略增强建设、数据安全持续运营”三个阶段在DataWorks上落地数据安全治理项目。参考本文启动数据安全治理项目前,建议您先了解DataWorks数据安全产品相关能力了解DataWorks数据安全产品能力后,您可参考如下三个阶段在DataWorks上落地数据安全治理项目。

soso1968的博客 1438

C++学习 十五、类继承(2)虚函数,多态

C++学习 十五、类继承(2)虚函数前言基类,派生类,指针虚函数与多态虚函数,virtual关键字多态 前言 本篇继续类继承的学习,虚函数 基类,派生类,指针 基类与派生类具有非常特殊的关系: 可以用派生类对象为基类对象赋值; 可以用派生类对象为基类对象初始化; 基类指针可以指向派生类对象; 基类引用可以绑定派生类对象。 上面四个关系反过来不成立。 #include <cstdio> #include <iostream> #include <cstring> us

qq_41035283的博客 448

NVIDIA Isaac GR00T N1 入门教程(一) 人形机器人多模态大语言模型

英伟达™ Isaac GR00T N1 是世界上首个用于通用仿人机器人推理和技能的开放式基础模型。该跨体模型采用多模态输入(包括语言和图像)在不同环境中执行操作任务。GR00T N1 在一个庞大的仿人机器人数据集上进行训练,该数据集包括真实捕获数据、使用英伟达 Isaac GR00T Blueprint 组件生成的合成数据(神经生成轨迹示例)以及互联网规模的视频数据。通过后期训练,它可以适应特定的应用、任务和环境。

2506_90492529的博客 3049

c++ 多态 学习总结2 纯虚函数和抽象类

纯虚函数基本语法:virtual 函数返回值类型 函数名(形参列表)=0 例如: virtual void func ()=0 抽象类:当类中有了纯虚函数,这个类称为抽象类 (注)只要类中有一个纯虚函数,这个类就是一个抽象类,并且它的子类也是抽象类,即使子类中没有纯虚函数。 抽象类的特点: 1.无法实例化对象(无论实在栈区还是在堆区都无法实例化) eg: #include <iostream> using namespace std; class Base { public:

chirou_的博客 567

一键生成Microsoft Store应用直链下载:绕过商店故障的终极方案

遇到商店无法加载时,复制链接 → 粘贴到Adguard → 下载主程序包 → 开启开发者模式安装。整个过程耗时不超过2分钟,彻底摆脱商店依赖!

安德洛夫 2187

手把手教你学simulink(44.1)--串励直流电动机场景示例:基于Simulink开发一个串励直流电动机电压控制仿真模型

高启动转矩:由于励磁绕组和电枢绕组串联连接,电机在启动时可以产生较大的转矩。速度随负载变化:由于励磁电流和电枢电流是同一电流,电机的速度会随着负载的变化而显著变化。适用于重载启动:适合用于需要高启动转矩的应用,如起重机、牵引系统等。

MHD0815的博客 340

C++ 学习笔记(2) 虚函数的使用 virtual

虚函数,是为了实现C++运行时的多态,而产生的。还有编译时的动态,那是重载实现的。特点1. 通过虚函数机制,子类可以重写基类的虚函数,同名的函数,在不同的子类中有多重实现。2. 基类可以通过指针,引用的方式,动态绑定子类,然后调用子类重写的虚函数(不是重写的函数不可以调用)。3. 基类中含有一个vtable 指针,指向一张表 —— 虚函数表,简称 “虚表” 。每个含有虚函数的类中都保存着一个指向虚...

Fluence_YHL 573

Codesys入门-新建工程+任务调用+编译+调试

程序组织单元(Program Organization Unit, POU)由声明区和代码区组成,是用户程序的最小软件单元,它相当于传统编程系统中的块(Block),按功能程序组织单元(POU)可分为函数(FUN)、功能块(FB)、程序(PRG)。:Codesys采用多任务的方式来执行用户程序的“任务”,而每个“任务”分配了不同的执行周期,有些全局变量可能要在不同的POU之间被访问和修改,于是需要对全局变量进行交互同步,也是在任务的“时间对准点”进行的,实例:声明了INT类型,变量名为输入;

刺客 1万+

C++学习日记2——多态篇的纯虚函数和抽象类

C++的纯虚函数和抽象类

阿木寺的博客 748

100天精通Oracle-实战系列(第14天)Veritas NetBackup(NBU) 配合 RMAN 脚本备份 Oracle 数据库

100天精通Oracle-实战系列(第14天)Veritas NetBackup(NBU) 配合 RMAN 脚本备份 Oracle 数据库

LuciferLiu_DBA 1993

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++学习笔记(2):构造函数是否可以是虚函数

虚函数表是属于类的, 不存在于对象的存储空间中;虚函数表指针是属于对象的, 存在于对象的存储空间中;生成对象,需要先调用对象类的构造函数, 如果对象类的构造函数是虚函数, 那么需要先知道虚函数表指针,然后根据虚函数表指针找到虚函数表,再指定调用构造函数, 此时虚函数表指针还没有被初始化指定(在构造函数中指定初始化), 这样就矛盾了, 因此构造函数是不能被声明为虚函数的。

tagagi的博客 734

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++学习——虚函数

今天来总结C++语言中极为重要的知识点——虚函数,包含常考面试题┗|`O′|┛ 嗷~~,一起来学习吧~

mingyuexin235的博客 3177

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

虚函数 2 之虚函数的定义

1、虚函数的定义 虚函数就是在基类中被关键字 virtual 说明,并在派生类中重新定义的函数。 虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。 虚函数的定义是在基类中进行的,它是在基类中在那些需要定义为虚函数的成员函数的声明中冠以关键字 virtual 。定义虚函数的方法如下: virtual 函数类型 函数名(形参表){ ...

aaqian1的博客 1万+

虚函数和纯虚函数的区别

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

Hackbuteer1的专栏 20万+

C++学习Day07之虚函数和纯虚函数

C++之虚函数和纯虚函数

似霰的博客 1320

虚函数、纯虚函数、多态

如果析构函数不被声明为虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样会造成派生类析构不完全,造成内存泄漏。由于我们只知道父类的类型,编译器无法确定指针指向的是哪个子类对象,因此只能调用父类的析构函数来释放资源。因为多态允许我们以统一的方式处理不同的派生类对象,并且在运行时确定要调用的方法。相反,它会在运行时根据对象的实际类型来选择正确的函数版本。这种机制允许多态性(Polymorphism)的实现,允许不同的派生类以不同的方式实现相同的虚拟函数。

Ricardo的博客 4486

【C++学习笔记】虚函数和虚函数表

虚函数就是在函数声明时使用关键字virtual修饰的成员函数。

2301_80160321的博客 1654

C++ 虚函数和纯虚函数

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

qq_39779233的博客 4185

虚函数与纯虚函数 -区别

构造函数不定义为虚函数构造函数是在实例化对象的时候进行调用,如果此时将构造函数定义成虚函数,需要通过访问该对象所在的内存空间才能进行虚函数的调用(因为需要通过指向虚函数表的指针调用虚函数表,虽然虚函数表在编译时就有了,但是没有虚函数的指针,虚函数的指针只有在创建了对象才有),但是此时该对象还未创建,便无法进行虚函数的调用。所以构造函数不能定义成虚函数。析构函数定义成虚函数。

weixin_48434590的博客 3341

虚函数及虚函数表

虚函数及虚函数表 各个类对象共享类的虚函数表,每个类对象有个虚函数指针vptr,虚函数指针vptr指向虚函数表(对于只有一个虚函数表的情况)。 虚函数 简单的说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类的所有虚函数对应的函数指针。 C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术

天空的博客 2906
上一篇: 虚函数学习(静态联编,动态联编,多态,构造,虚析构,delete)
下一篇: vc包含路径/附加包含路径/include的机制
不说害怕
博客等级 码龄20年 100粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值