c++虚函数&重写
虚函数是C++中实现多态的一种方法,父类A的一个函数声明为虚函数,在子类B中覆盖定义之后,当在调用的时候使用A*a=new B(),此时调用对应的那个虚函数的名字,则会执行B中的函数。当父类中没有定义虚函数的实体时候,virtual void foo()=0;这个函数就是一个纯虚函数,对应的父类就是抽象类,则这个抽象类不能被实例化,只能由子类派生实例化。
每个含有虚函数的对象都有一个虚指针,这个虚指针和这个对象的基地址是一样的,即一个对象的第一块内存单元存储的一定这个类对象的虚指针。
普通继承中,B对象中只有一个虚指针,这个指针指向A、B中的所有虚函数存在的虚表;对于虚拟继承来讲,在B的对象中会有两个虚指针,一个是仅仅只有A对象的虚表,另一个指针是A、B所有的虚函数虚表指针。当然,包含A、B所共有的虚函数的虚表指针是和B在同一个基地址上的,即B对象的第一个单元的指针即是虚表指针。另外还需要注意的是当B覆盖了A中定义的虚函数之后,B对象中的仅仅只有A的虚函数的那个虚指针所在的虚表项目会做调整,里面的函数指针指向的是覆盖后的函数(B中的函数)。
还有一个地方需要注意,就是虚函数和重载函数的问题。虚函数重写的时候是允许返回值有差异的,但是对参数的要求很严格。遵循以下规则:
a) 参数必须类型一样,即使有继承关系也不行,Base* Base::copy(Base*); Base* Derived::copy(Derived*),这样是不能够达到虚函数的效果的;
b) 参数类型一样,而且也允许在父类中有默认值,则子类继承这个默认值,即ostream& Base::print(int,ostream&=cout); ostream& Derived::print(int,ostream&);这样的写法是允许的,而且这个默认值写在子类和父类都是可以的,若写在父类中,使用子类调用的时候默认值必须写上;
c) 对于函数const属性修饰符,若一个加一个没有加,则看成是重载函数而不是重写;
d) 返回类型若是基本类型,则必须保持一样,否则会报错;返回类型若是类对象,则可以允许返回值之间有继承关系(直接/间接继承都可以)即可(菱形继承除外)
c++虚函数&重写的更多相关文章
- c++虚函数重写的权限问题
cbase.h: #ifndef CBASE_H #define CBASE_H #include<iostream> using std::cout; using std::endl; ...
- 匹夫细说C#:从园友留言到动手实现C#虚函数机制
前言 上一篇文章匹夫通过CIL代码简析了一下C#函数调用的话题.虽然点击进来的童鞋并不如匹夫预料的那么多,但也还是有一些挺有质量的来自园友的回复.这不,就有一个园友提出了这样一个代码,这段代码如果被编 ...
- 你好,C++(37)上车的人请买票!6.3.3 用虚函数实现多态
6.3.3 用虚函数实现多态 在理解了面向对象的继承机制之后,我们知道了在大多数情况下派生类是基类的“一种”,就像“学生”是“人”类中的一种一样.既然“学生”是“人”的一种,那么在使用“人”这个概念 ...
- C++基础 (7) 第七天 多态的原理 纯虚函数和抽象类 依赖倒置原则
1 昨日回顾 2 多态的原理 1 要有继承 2 要有子类重写父类的虚函数 3 父类指针(或者引用)指向子类对象 (动态联编 虚函数表 3 证明vptr指针的存在 4 vptr指针在构造父类的时候是分步 ...
- 虚函数重载(overwrite) 继承覆盖问题
引言 类接口需要添加默认参数,以适应不同情况调用, 但是clang-tidy 不允许在接口上设置默认参数,ps: 可能担心继承类里接口重新设置新默认参数而导致误用的情况 #include <st ...
- c++中的函数重载、函数重写、函数重定义
目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...
- cc32a_demo-32dk2j_cpp_纯虚函数与抽象类-txwtech
//32dk2j_cpp_纯虚函数与抽象类cc32a_demo-txwtech//纯虚函数是用来继承用的//纯虚函数//抽象类-抽象数据类型//*任何包含一个或者多个纯虚函数的类都是抽象类//*不要/ ...
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- c# 基础(重写与覆盖:接口与抽象,虚函数与抽象函数)
总结 1:不管是重写还是覆盖都不会影响父类自身的功能(废话,肯定的嘛,除非代码被改). 2:当用子类创建父类的时候,如 C1 c3 = new C2(),重写会改变父类的功能,即调用子类的功能:而覆盖 ...
随机推荐
- javascript修改div大小遮挡页面渲染问题
页面中引入了其他js文件,浏览器窗口改变,页面没有跟随渲染问题.最后找到原因是因为这个js方法少了最后一行: "right": RightBox_w. window.onresiz ...
- nigix安装
树莓派安装nginx,参考http://blog.csdn.net/zizi7/article/details/54347223 1. 下载PCRE 并安装. 主页地址: ftp://ftp.csx. ...
- iOS App之间常用的五种通信方式及适用场景总结
iOS系统是相对封闭的系统,App各自在各自的沙盒(sandbox)中运行,每个App都只能读取iPhone上iOS系统为该应用程序程序创建的文件夹AppData下的内容,不能随意跨越自己的沙盒去访问 ...
- Scrum 项目2.0 3.0
顺带 MY—HR 成员: 角色分配 学号 博客园 团队贡献分 丘惠敏 PM项目经理 201406114203 http://www.cnblogs.com/qiuhuimin/ 19 郭明茵 用户 2 ...
- Littleproxy的使用
介绍 LittleProxy是一个用Java编写的高性能HTTP代理,它基于Netty事件的网络库之上.它非常稳定,性能良好,并且易于集成到的项目中. 项目页面:https://github.com/ ...
- PHP 内置函数strlen 和mbstring扩展函数mb_strlen的区别
#EXAMPLE $str_uncode = "简体中文Chinese(Simplified)"; //统计字符串长度 echo strlen($str_uncode).'< ...
- PHP开发网站,你是如何提高其网站的安全性的?
一.网站程序问题 很多网站的安全问题大多是由于网站程序存在漏洞,所以想要提高网站安全性,必须要选择安全的后台cms系统,若有能力可以自己去开发网站后台,这样安全性能得到极大的提高,若是从网上选择一些免 ...
- java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
微信小程序前后台使用get方式传参时报错如图.但在微信开发平台和苹果测试都没事,在安卓手机上就报这个错,猜想原因是get传递了汉字的原因. 尝试了下在后台输出从前台获取的参数,但是后台什么也没有获取到 ...
- C++模式学习------原型模式
原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.意思就是从A的实例得到一份与A内容相同,但是又互不干扰的实例B. class base { public : base(co ...
- DPDK环境搭建
一.环境要求 1.内核版本 >= 2.6.34: 2.glibc版本 >= 2.7 (ldd --version 查看glibc版本): 3.gcc版本 >= 4.9,一些gc ...