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字节)。每个虚函数调用,都需要执行地址查找。

参考:

1.关于C++中的虚拟继承的一些总结

C++的继承与接口的更多相关文章

  1. Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  2. C#类继承和接口继承时一些模棱两可的问题[转]

    原文地址:http://www.cnblogs.com/harleyhu/archive/2012/11/29/2794809.html 1.在father定义的方法若含有virtual关键字,chi ...

  3. Java继承和接口

    接口最关键的作用,也是使用接口最重要的一个原因:能上溯造型至多个基础类.使用接口的第二个原因与使用抽象基础类的原因是一样的:防止客户程序员制作这个类的一个对象,以及规定它仅仅是一个接口.这样便带来了一 ...

  4. 基础学习day07---面向对象三---继承,接口与 抽象类

    一.继承 1.1.继承概念 将对象的共性抽取出来.提取出一个单独的类. 继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性 继承使重一个类A能够直接使用另外一 ...

  5. java 类的继承和接口的继承

    父类 public class person { String name; int age; void eat(){ System.out.println("吃饭"); } voi ...

  6. Effective C++ 笔记:条款 34 实现继承和接口继承

    Differentiate between inheritance of interface and inheritance of implementation. 行为含义 声明一个pure virt ...

  7. 【C# 复习总结】类、继承和接口

    1 类 定义新的数据类型以及这些新的数据类型进行相互操作的方法 定义方式: class Cat { } class Cat:object { } C#中所有的类都是默认由object类派生来的,显示指 ...

  8. Javascript面向对象特性实现封装、继承、接口详细案例

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  9. java基础知识总结--继承和接口

    什么是继承?什么是接口?他们之间的区别和联系是什么? 什么是继承? 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能.多个类中存在相同属性和行 ...

  10. PHP接口继承及接口多继承原理与实现方法详解

    在PHP的接口中,接口可以继承接口.虽然PHP类只能继承一个父类(单继承),但是接口和类不同,接口可以实现多继承,可以继承一个或者多个接口.当然接口的继承也是使用extends关键字,要多个继承的话只 ...

随机推荐

  1. php如何查看扩展是否开启

    php如何查看扩展是否开启 一.总结 一句话总结:php -m 1.查看php已安装扩展命令 ? php -m 2.phpinfo();这是最常用的方法,但那么多扩展一时还真不太好找.? 3.exte ...

  2. rabbitmq_学习_01_rabbitmq安装

    二.参考资料 1.RabbitMQ:windows10下安装 2.RabbitMQ系列(一):Windows下RabbitMQ安装及入门

  3. WordPress发布文章前强制要求上传特色图像

    如果你的网站需要给每篇文章设置特色图像才能达到理想的显示效果,而且允许其他用户在后台发布文章的,那么您可能需要强制要求他们给文章上传特色图像,否者就无法发布.Require Featured Imag ...

  4. 获得客户端ip

    获得客户端ip private function GetIP(){        if(!empty($_SERVER["HTTP_CLIENT_IP"])){          ...

  5. Tomcat的安装与环境配置

    首先,下载地址为:http://tomcat.apache.org/,在左侧的列表中找到Download,找到自己要下载的Tomcat的版本.我下载的是Tomcat 7. 进入后出现如上右图界面.我选 ...

  6. LeetCode Base 7

    原题链接在这里:https://leetcode.com/problems/base-7/#/description 题目: Given an integer, return its base 7 s ...

  7. Unity物体上下反复漂浮效果

    using UnityEngine;using System.Collections;// 主界面的开始按钮使用该脚本,控制上下来回浮动public class Floating : MonoBeha ...

  8. mysql之 xtrabackup原理、备份日志分析、备份信息获取

    一. xtrabackup备份恢复工作原理: extrabackup备份简要步骤 InnoDB引擎很大程度上与Oracle类似,使用redo,undo机制,XtraBackup在备份的时候,以read ...

  9. MyEclipse启动tomcat增加内存配置

    omcat增加内存在catalina.bat下 MyEclipse增加内存 设置Window->Preferences->Application Servers->Tomcat -- ...

  10. 6、Selenium+Python登录案例 -- Github

    一:登录 1.指定浏览器,打开网址:https://github.com/login 2.设置等待时间: time.sleep(3) or driver.implicitly_wait(3) 3.输入 ...