虚函数,抽象基类

news/2025/1/12 23:38:57/

编译器处理虚函数的方法:

给每个对象添加一个隐藏成员,隐藏成员保存了一个指向函数地址的数组指针,数组被称为虚函数表,虚函数表存储了为类对象声明的虚函数的地址,比如基类包含一个指针,该指针指向基类中所有的虚函数的地址查找表,派生类将继承这个虚函数地址表,如果重新定义了虚函数,那么派生类的虚函数表中相应的函数地址会被替换,调用虚方法的时候,函数调用的就是这个虚地址里的函数,由于被替换,所以可以用基类指针调用派生类方法,调用虚函数时,程序将查看虚函数表中的地址,并转向相应的函数地址表,

总之使用虚函数的时候,在内存和执行速度上都有一定的成本,包括:

每个对象都将增大,增大量为存储虚函数地址的数组的空间;

对于每个类,编译器都要创建一个虚函数地址表;

对于每个函数调用,都需要执行一项额外操作,即到表中查找地址;

虽然非虚函数比虚函数效率高,但不具备动态联编功能;

析构函数必须是虚析构函数:这是由于基类指针指向派生类对象造成的;

虚函数与抽象基类是不一样的;

友元不能是虚函数,只有成员函数才能是虚函数,

如果定义的类被用作基类,则应该将那些在派生类中重新定义的方法声明为虚的,析构函数是一定会被重载的,因此析构函数必须是虚函数;构造函数不能是虚函数,调用顺序是先调用基类构造函数,在调用派生类构造函数,如果是虚方法,则将调用派生类的构造函数,然后调用基类的构造函数,这与继承的机制相反;

如果派生类中重新定义的函数与基类虚函数的函数特征标不同即重载,那么将隐藏基类虚函数,根据返回类型协变,如果只是修改返回值,将不会隐藏基类虚函数,

如果确实有必要重载基类虚函数(函数特征标不同),那么应该在派生类中重载所有的基类版本,如果只重载一个版本,那么另外的将被隐藏,

 如上,Hovel必须重写所有的基类虚函数,这也不能通过作用域解析运算符来调用,

总结虚函数注意:

当定义为虚函数时,通过指针或引用调用时,调用的函数为指向对象的类型中的函数,而不是指针的类型下的函数;

虚函数表:虚函数的调用方式:指针在指针指向的对象的虚函数数组内找到要调用的函数指针地址,然后调用,所以虚函数可以调用指针指向类型的函数;由于虚函数表的存在,他只与对象有关,

隐藏基类方法:如果子类对虚函数进行重载,将隐藏基类的虚函数,因此如果重载,则必须重新定义所有的同名基类虚函数;

总的来说,虚函数是对于单继承模式下函数多态的一种拓展,当出现菱形继承时情况还会复杂一些;

抽象基类:

is-a关系是数学中的包含关系,一个集合属于另一个集合,但是当两个集合出现相交时就有问题了,比如圆是特殊的椭圆,但椭圆类有两个焦点,圆只有一个圆心,即属性成员出现了冲突,除此之外圆和椭圆可以发生的动作也是不同的,是不能通过函数重载来解决的, 单独定义两个类似乎更简单一些;

抽象基类说明:

但是圆和椭圆是由共同点的,也就是说这种相交关系更像是同辈,而不是父子,因此可以给他们两个指定一个基类,包含他们的交集,有时这种类不需要被实例化,此时我们称这种类为抽象基类,比如圆和椭圆的抽象基类,按理来说他是一个图形,但它只包括了中心点的坐标,他没有半径,长短焦距这些参数,那么他其实无法实例化为一个图形,这时它理论上就无法被实例化,同时实际上他也没有必要被实例化,那么他就成为一个抽象基类就好了,这点我们可以这么来举例:人和狮子是哺乳动物的派生类,但哺乳动物无法被实例化,他有几个脚?几个眼睛?什么样的运动方式?都没有,怎么运动?如果没有运动,只是声明的话是没有内存空间的,程序就没法访问它,对于没有实际意义的动作,就把他们声明为纯虚函数,对于没有意义的属性,直接不声明它,那么哺乳动物就是一个它通过加入纯虚函数来实现,

纯虚函数的结尾处为 =0;如下图中的

virtual double Area()const =0;

纯虚函数也可以有定义,但他不能同时是内联的,即不能再类声明中定义;

概念称呼:哺乳动物是抽象类,人和狮子就是具体类,即可以创建对象的类,

成为具体类的方法:要想成为具体类就必须重写所有的基类的纯虚函数;

所有的当类与动态内存分配结合起来时,情况就会很微妙;如果再加上继承,

动态内存分配涉及到复制构造函数,析构函数,重载赋值运算符,当出现需要动态内存分配的初始化的指针成员时,必须重载这三个指令集,

否则会出现内存泄漏(析构函数)和浅拷贝(赋值运算符,复制构造函数)以及重复清理堆空间(析构函数),


http://www.ppmy.cn/news/590647.html

相关文章

TGBUS主页面 HTML的编写

主代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title></title><link rel"stylesheet" type"text/css" href"yangshi.css"> </head> <body><div …

四六级议论文写作万能句

目录 开篇万能句式 描写图表、图画万能句式 中间段万能句式 表达个人观点 分析原因 强调重要性 论述事物的两面性 论述事物的对比 总阶段万能句式 总结观点 提出建议 建议后的万能句式 开篇万能句式 1.There is a general belief that ... However&#xff0c;...…

经典美剧

1《老友记》 Friends&#xff0c;1994—2004&#xff0c;NBC 2《我爱露西》I Love Lucy&#xff0c;1951-1957&#xff0c;CBS 3《宋飞传》Seinfeld&#xff0c;1989-1998&#xff0c;NBC 4《风流医生俏护士》M*A*S*H&#xff0c;1972-1983&#xff0c;CBS 5《六尺之下》Si…

最短的恐怖推理故事

悬疑恐怖故事&#xff0c;你看懂了第几个。没有唯一答案&#xff0c;有理就是正确的。欢迎分享~ 以下内容转自网络&#xff0c;仅供娱乐&#xff0c;切勿太当真&#xff01; 1、年龄 我搭上了一列特快车&#xff0c;大概在还差10分就午夜12点的时候&#xff0c;在中途站有一名男…

只有运用你的逻辑才能看懂其中的恐怖及答案

看着比较有意思就转了。答案见末尾 1、年龄 我搭上了一列特快车&#xff0c;大概在还差10分就午夜12点的时候&#xff0c;在中途站有一名男子也上了列车&#xff0c;他在车门关闭后&#xff0c;像是突然回复意识一般&#xff0c;开始左右环视着周遭乘客的脸。 “恕我愚昧&#…

SQL Server之菜鸟入坑学习练习01

use Student; --建立学生表 create table stu_( stu_num int primary key, stu_name varchar(20) not null, sty_sex varchar(20) default 男 check(sty_sex男 or sty_sex女 or sty_sex未知) not null, stu_class varchar(20) ); -- drop table stu_; --往学生表插入数据 inser…

十二个“一”---十二位胜似亲人的悲情向团体详解

作业要求&#xff1a; 任务主题&#xff1a;对“十二个’一’文艺创作”进行拓展&#xff1b; 任务要求&#xff1a;字数不少于8000字&#xff08;配图算100字&#xff0c;原创插图&#xff0c;视复杂程度&#xff0c;算作200~1000字&#xff0c;具体可预先展示给老师评估&…

转载:声优 - 野上ゆかな

转自:http://bbs.52wy.com/viewthread.php?tid=5025 【旧名】 野上 ゆかな (Nogami Yukana)[2001年4月1日改名] 【所属事务所】 Salir/Sigma7参加 【出生地】 千叶县 【生日】 1975年1月6日 【血型】 O型 【兴趣/特长】 书法、音乐、民间介护 【Fan Club】 Copine 【备注】 …