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(),重写会改变父类的功能,即调用子类的功能:而覆盖 ...
随机推荐
- 蜗牛慢慢爬 LeetCode 36.Valid Sudoku [Difficulty: Medium]
题目 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- LinkedList,HashSet,HashMap
LinkedList底层源码是采用双向链表实现的 private static class Node<E> { E item;//节点值 Node<E> next;//节点后指 ...
- java 数据结构与算法---二叉树
原理来自百度百科 推荐数据演示网址 :https://www.cs.usfca.edu/~galles/visualization/BST.html 一.什么是二叉树 二叉树的每个结点至多只有 ...
- onMeasure实例分析
本文转自:http://blog.csdn.net/u012604322/article/details/17097105 上面这个两个视图是Android API中没有给出来的但 ...
- 半夜思考, Java 重载的实现
因为最近在学 scala,看到了参数的默认值这个特性,但是Java好像没有这个特性, Java8 也没有, 所以特意去查了一下,就牵扯到了 C++了,[只怪 C++没怎么学,,]. 下面将一下为什么 ...
- 利用ZooKeeper简单实现分布式锁
1.分布式锁的由来: 在程序开发过程中不得不考虑的就是并发问题.在java中对于同一个jvm而言,jdk已经提供了lock和同步等.但是在分布式情况下,往往存在多个进程对一些资源产生竞争关系,而这些进 ...
- python自动化之邮件发送
#!/usr/bin/env python # -*- coding:utf-8 -*- import smtplib from email.mime.multipart import MIMEMul ...
- c++11 线程的互斥量
c++11 线程的互斥量 为什么需要互斥量 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源.这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在 ...
- MT【144】托兰定理【图论】
平面上$2n$个点$(n>1,n\in N)$,无三点共线,任意两点连线段,将其中任意$n^2+1$条线段染红色. 求证:三边都为红色的三角形至少有$\left[\dfrac{2}{3}(n+\ ...
- 使用mshta.exe绕过应用程序白名单(多种方法)
0x00 简介 很长一段时间以来,HTA文件一直被web攻击或在野恶意软件下载程序用作恶意程序的一部分.HTA文件在网络安全领域内广为人知,从红队和蓝队的角度来看,它是绕过应用程序白名单有价值的“ ...