C++中的继承与虚函数各种概念
虚继承与一般继承
虚继承和一般的继承不同,一般的继承,在目前大多数的C++编译器实现的对象模型中,派生类对象会直接包含基类对象的字段。而虚继承的情况,派生类对象不会直接包含基类对象的字段,而是通过一个间接的指针去存取基类对象中的字段。
虚函数的实现原理
当编译器对程序进行编译碰到虚函数时,将不会赋予一个地址,而是插入一段汇编代码。每个包含虚函数的类都会由编译器产生一个虚函数表和一个虚函数表指针,其中虚函数表指针放在每个类的首地址处。当程序执行时,碰到对虚函数的调用,则通过插入的汇编代码到当前类的地址中找到虚函数表指针,通过虚函数的序号找到需要调用的虚函数。注意,一个系列的类的虚函数表中某一个函数的序号是一样的。而且,编译器会保证在使用父类指针操作子类对象时只能在父类已有的虚函数上实现虚函数的机制。
继承中的接口及其实现
虚函数实际上就是继承中的一种接口。继承中一共有纯虚函数、非纯虚函数和非虚函数三种接口,它们在子类中的处理如下:
1.纯虚函数:所有子类必须强制性地改写,否则会报错。这是一种仅仅继承接口的方法。
2.非纯虚函数:又被称为简单虚函数,可以在基类中有自己的实现(默认的动作),子类不一定要改写,这是一种继承接口及其默认实现的方法。
3.非虚函数:子类最好不要改写,这是一种强制性地继承接口及其实现的方法,表示的是一种共性。
当在同一个类中存在同名但是参数不同的函数,叫作overloading(重载);子类改写父类的虚函数,叫做overriding(覆盖);子类改写父类的非虚函数,叫做redefining(重定义),这是不推荐的。
虚函数、纯虚函数、虚基类、抽象类、虚函数继承、虚继承-------各种概念解释
虚函数:
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。是C++中多态性的一个重要体现,利用基类指针访问派生类中的成员函数,这种情况下使用虚函数,这种情况下采用的是动态绑定技术。
虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
virtual 函数返回值类型 虚函数名(形参表)
{ 函数体 }
动态绑定:
基类指针是调用派生类的中的成员函数还是调用基类中的成员函数要到程序运行时确定。主要要看指针所指向的对象。
纯虚函数:
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion1()=0
虚基类、抽象类:
当派生类虚拟继承基类时,基类为派生类的虚基类。包含纯虚函数的类称为抽象类,由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
虚函数继承:
虚函数继承就是覆盖。即基类中的虚函数被派生类中的同名函数所覆盖。 是实现多态的方法。
虚继承:
解决多重继承中派生类成员函数调用模糊问题。比如类A中有一个函数print(),类B继承A,类C继承A,类D继承类B和类C,这个时候,类D中就有两个print函数,一个是从B继承得到的,一个是从C继承得到的,则类D的对象调用print函数就会出现print模糊的编译错误。解决办法:类B虚拟继承A。类C虚拟继承A,类D继承B,C时,只拷贝A中的数据成员和函数成员一次,再遇到拷贝时候就忽略了!
虚继承就是为了节约内存的,他是多重继承中的特有的概念。适用与菱形继承形式。
如:类B、C都继承类A,D继承类B和C。为了节省内存空间,可以将B、C对A的继承定义为虚拟继承,此时A就成了虚拟基类。
class A;
class B:public vitual A;
class C:public vitual A;
class D:public B,public C;
@:http://www.sctarena.com/Article/Article.asp?nid=2966
关于虚表:陈皓——C++ 虚函数表解析
C++中的继承与虚函数各种概念的更多相关文章
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- C++ Pirmer : 第十五章 : 面向对象程序设计之基类和派生的定义、类型转换与继承与虚函数
基类和派生类的定义以及虚函数 基类Quote的定义: classs Quote { public: Quote() = default; Quote(cosnt std::string& bo ...
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- c++虚继承与虚函数
学习继承与多态时看到这两个概念,记录整理. 虚继承与虚函数都是用virtual关键字实现,虚继承为了防止多重继承,而虚函数为了实现多态. 是几个例子. 虚继承: class A{}; class B: ...
- 转 C++中不能声明为虚函数的有哪些函数
传送门 C++中不能声明为虚函数的有哪些函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数 ...
- C++多重继承分析——《虚继承实现原理(虚继承和虚函数)》
博客转载:https://blog.csdn.net/longlovefilm/article/details/80558879 一.虚继承和虚函数概念区分 虚继承和虚函数是完全无相关的两个概念. 虚 ...
- C++中的多态与虚函数的内部实现
1.什么是多态 多态性可以简单概括为“一个接口,多种行为”. 也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可 ...
- C++中不能声明为虚函数的有哪些函数
常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被o ...
- C++学习笔记(十二):类继承、虚函数、纯虚函数、抽象类和嵌套类
类继承 在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生. 从一个基类派生的继承称为单继承:从多个基类派生的继承称为多继承. //单继承的定义 class B:public A { ...
随机推荐
- java树型结构的数据展现设计
在做一个需求管理的页面时,需求的展现是不限层级树型结构,需求下还可以分拆任务,页面要展现的字段有20多个,而且需求采用通用表单设计,db采用大宽表存储,有一百多个字段.目前数据量不大,第一版采用普通的 ...
- Windows提高_2.3第三部分:内核区同步
第三部分:内核区同步 等待函数(WaitForObject) 等待函数的形式 单个:WaitForSingleObject 多个:WaitForMultipleObjects 一个可以被等待的对象通常 ...
- SDK_组合框的使用
组合框的使用 组合框的创建:有三种风格,分别 Simaple,Dropdown(可输入), 下拉列表(不可输入) 可以通过可视化编程中下拉列表的 下拉箭头 设置列表的长度 如何向组合框控件中添加数据, ...
- CAD得到所有实体1
主要用到函数说明: IMxDrawSelectionSet::AllSelect 得到当前空间的所有实体.详细说明如下: 参数 说明 [in,defaultvalue(NULL)] IMxDrawRe ...
- Eigen库笔记整理(二)
Eigen/Geometry 模块提供了各种旋转和平移的表示 旋转矩阵直接使用 Matrix3d 或 Matrix3f Eigen::Matrix3d rotation_matrix = Eigen: ...
- pl/sql编程语言
–pl/sql编程语言–pl/sql编程语言是对sql语言的扩展,是的sql语言具有过程化编程的特性–pl/sql编程语言比一般的过程化编程语言,更加灵活高效–pl/sql编程语言主要用来编写存储过程 ...
- BZOJ 1058: [ZJOI2007]报表统计 multiset + 卡常
Code: #include<bits/stdc++.h> #define maxn 600000 #define inf 1000000000 using namespace std; ...
- Java基础——异常
一.什么是异常 异常的英文单词是exception,字面翻译就是“意外.例外”的意思,也就是非正常情况.事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误.比如使用空的引用.数组下标越界. ...
- zip相关知识梳理(一)
zip相关知识梳理(一) 经过对zip文件的长时间研究,对zip文件进行相关知识进行梳理,虽然网上很多牛人对其做了相关基础解析,但是对于特殊情况没有进行说明,比如超过4G的zip文件该以什么格式进行编 ...
- 题解 洛谷P3203/BZOJ2002【[HNOI2010]弹飞绵羊】
裸的LCT,关键是要怎么连边,怎么将这种弹飞关系转化成连边就行了. 那么我们可以这样连边: 一个节点i的爸爸就是i+ki. 没有i+ki那么就被弹飞了,即\(i\)的爸爸是虚拟节点n+1. 那么怎么求 ...