C++的继承与接口
1.继承方式
三种继承方式,public,private,protected。注意,继承方式是相对于某一层类的方法而言,并不是相对于子类的对象而言。对于外部世界()对象来说,protected和private相似。对于派生类来说,protected和public相似。
public继承。派生类中,父类public和protected的成员可以直接访问,仍旧保持public属性。派生类对象,父类public成员可以访问。
private继承。派生类中,父类public和protected的成员可以直接访问,但是已经成为了private属性。直接后果:其一是派生类对象不能直接访问这些成员了(类外私有);其二、派生类的子类也不能直接访问这些成员了(已经私有属性,只能经由该层派生类访问)。
protected继承。派生类中,父类public和protected的成员可以直接访问,但是已经成为了protected属性。直接后果:派生类对象不能不能直接访问这些成员了(私有),同样派生类的子类可以继访问(protected)。
总结而言:
基类中 继承方式 子类中
public & public继承 => public
public & protected继承 => protected
public & private继承 = > private
protected & public继承 => protected
protected & protected继承 => protected
protected & private继承 = > private
private & public继承 => 子类无权访问
private & protected继承 => 子类无权访问
private & private继承 = > 子类无权访问
2.虚继承
虚继承时为了解决多重继承出现的钻石继承导致子对象重复。虚继承可以节省内存。当然节省了内存牺牲了时间。相较于普通继承而言,虚继承:
(1)时间上在通过继承类对象访问虚基类对象中的成员(包括数据成员和函数成员)时,都必须通过某种间接引用来完成,这样会增加引用寻址时间(就和虚函数一样),其实就是调整this指针以指向虚基类对象,只不过这个调整是运行时间接完成的。
(2)空间上由于共享所以不必要在对象内存中保存多份虚基类子对象的拷贝,这样较之多继承节省空间(避免了同时出现两个基类子对像)。在虚拟继承情况下,基类子对象的布局是不同于普通继承的。因此,它需要多出一个指向基类子对象的指针。
考虑以下情况:
分别求sizeof(a),sizeof(b)。结果为:
第一种:4,12
第二种:4,4
第三种:8,16
第四种:8,8
分析:
考虑a: 涉及到内存对齐(由于每一个类均有虚函数,每个对象隐含保存虚指针指向类虚函数表,大小占4),故a的大小很好判断。
考虑b: 实际上:
第一个:vfptr(b:foo)+vbptr+vfptr(a:func)=12
第二个:vfptr(a:func, b:foo)=4
第三个:vfptr(b:foo)+vbptr+vfptr(a:func)+x(对齐为四个字节)=16
第四个:vfptr(a:func, b:foo)+x(对齐为四个字节)=8
含有虚函数的类均有指向自身虚函数表的虚指针。只是虚继承时,虚函数表仅有自身的虚函数地址,而非虚函数,且每一层的虚指针都存在,且派生类包括一个指向父类对象的虚指针。对于非虚继承,始终有且仅有一个虚指针,且包含所有虚函数地址。
同样:
class A{
char k[3];
public :
virtual void a(){};
};
class B1:public virtual A{
char k[3];
public :
virtual void b(){};
};
class C1:public virtual B1{
char k[3];
public :
virtual void c(){};
};
class B2:public A{
char k[3];
public :
virtual void b(){};
};
class C2:public B2{
char k[3];
public :
virtual void c(){};
};
A B1 C1 大小为8 20 32
A B2 B1 大小为8 12 16
3.重载、覆盖、隐藏的区别
重载:类内重载,同名不同参数。注意,虚函数也可以有包含重载类型,此时派生类必须对所有重载类型再次定义。
覆盖:派生覆盖,即派生类函数覆盖基类函数,同名同参且为虚函数。即虚函数机制属于覆盖类型。
隐藏:派生隐藏,即派生类的函数屏蔽了基类函数,同名不要求参数。虚函数也存在隐藏现象,即派生类存在同名不同参数的虚函数,会导致基类同名虚函数被隐藏。
4.虚指针与虚函数表
(1)虚(函数)指针用于虚函数的实现细节,带虚函数的类的每一个对象都有一个虚指针指向该类的虚函数列表。
(2)每个虚函数都在虚函数表占有一个地址。派生类对象包含指向独立地址表的指针。若提供了虚函数的新定义,则虚函数表保持性函数的地址,否则保留父类虚表的地址。
(3)不论类中有多少虚函数。类的对象只有一个虚函数指针指向该类的虚表。
(4)使用虚函数时。每个对象存储都增大,即包含指针存储空间(通常4字节)。每个虚函数调用,都需要执行地址查找。
参考:
C++的继承与接口的更多相关文章
- Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇
Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...
- C#类继承和接口继承时一些模棱两可的问题[转]
原文地址:http://www.cnblogs.com/harleyhu/archive/2012/11/29/2794809.html 1.在father定义的方法若含有virtual关键字,chi ...
- Java继承和接口
接口最关键的作用,也是使用接口最重要的一个原因:能上溯造型至多个基础类.使用接口的第二个原因与使用抽象基础类的原因是一样的:防止客户程序员制作这个类的一个对象,以及规定它仅仅是一个接口.这样便带来了一 ...
- 基础学习day07---面向对象三---继承,接口与 抽象类
一.继承 1.1.继承概念 将对象的共性抽取出来.提取出一个单独的类. 继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性 继承使重一个类A能够直接使用另外一 ...
- java 类的继承和接口的继承
父类 public class person { String name; int age; void eat(){ System.out.println("吃饭"); } voi ...
- Effective C++ 笔记:条款 34 实现继承和接口继承
Differentiate between inheritance of interface and inheritance of implementation. 行为含义 声明一个pure virt ...
- 【C# 复习总结】类、继承和接口
1 类 定义新的数据类型以及这些新的数据类型进行相互操作的方法 定义方式: class Cat { } class Cat:object { } C#中所有的类都是默认由object类派生来的,显示指 ...
- Javascript面向对象特性实现封装、继承、接口详细案例
Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...
- java基础知识总结--继承和接口
什么是继承?什么是接口?他们之间的区别和联系是什么? 什么是继承? 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能.多个类中存在相同属性和行 ...
- PHP接口继承及接口多继承原理与实现方法详解
在PHP的接口中,接口可以继承接口.虽然PHP类只能继承一个父类(单继承),但是接口和类不同,接口可以实现多继承,可以继承一个或者多个接口.当然接口的继承也是使用extends关键字,要多个继承的话只 ...
随机推荐
- 反射+type类+Assembly+特性
什么是元数据,什么是反射: 程序是用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据. 有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程 ...
- nginx安装目录
1.rpm -ql nginx看看通过yum安装到哪里了 2./etc/logrotate.d/nginx 配置 nginx日志轮转 用于logrotate服务的日志切割 3./etc/ngin ...
- jquery的插件选择chosen的使用
版权声明:本文为博主原创文章,未经博主允许不得转载.http ://blog.csdn.net/jobschen/article/details/46619443 一,文件引入 jquery // j ...
- 201621123014《Java程序设计》第六周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 答: 注1:关键词与内容不求多,但概念之间的联系 ...
- Codeforces Round #242 (Div. 2)C(找规律,异或运算)
一看就是找规律的题.只要熟悉异或的性质,可以秒杀. 为了防止忘记异或的规则,可以把异或理解为半加运算:其运算法则相当于不带进位的二进制加法. 一些性质如下: 交换律: 结合律: 恒等律: 归零律: 典 ...
- 利用Fiddler或Charles进行mock数据创造测试环境
使用场景:服务器数据不符合测试条件时,我们可以通过在本地创建虚拟数据来打到测试用例所描述的条件. fiddler使用方法 1.首先在本地创建txt数据:将抓到的response中的json数据拷贝到记 ...
- HihoCoder1415后缀数组三·重复旋律3
重复旋律3 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多 ...
- python_根据"词库"进行“词联想”
输入法中,当你输入一个字的时候,输入法就能猜出你要输入什么词.这就是词联想.现在,再python中简单实现类似这样的功能:根据制定好的词库,输入一个新的词,帮助实现词联想.其中分词用了jieba包. ...
- PostgreSQL学习手册 性能提升技巧
http://www.cnblogs.com/mchina/archive/2012/08/11/2537393.html 一.使用EXPLAIN: PostgreSQL为每个查询都生成一个查询 ...
- Shiro-RememberMe
概述 认证和记住我 建议 身份验证相关 实现 如果要自己做RememeberMe,需要在登录之前创建Token:UsernamePasswordToken(用户名,密码,是否记住我),且调用 User ...