虚继承这个东西用的真不多。估计也就是面试的时候会用到吧。。

可以看这篇文章:《关于C++中的虚拟继承的一些总结

虚拟基类是为解决多重继承而出现的。

如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下:

class A

class B1:public virtual A;

class B2:public virtual A;

class D:public B1,public B2;

一旦离开了多重继承,虚拟继承就完全失去了存在的必要因为这样只会降低效率和占用更多的空间。

2.引入虚继承和直接继承会有什么区别呢

由于有了间接性和共享性两个特征,所以决定了虚继承体系下的对象在访问时必然会在时间和空间上与一般情况有较大不同。

2.1时间:在通过继承类对象访问虚基类对象中的成员(包括数据成员和函数成员)时,都必须通过某种间接引用来完成,这样会增加引用寻址时间(就和虚函数一样),其实就是调整this指针以指向虚基类对象,只不过这个调整是运行时间接完成的。

2.2空间:由于共享所以不必要在对象内存中保存多份虚基类子对象的拷贝,这样较之多继承节省空间。虚拟继承与普通继承不同的是,虚拟继承可以防止出现diamond继承时,一个派生类中同时出现了两个基类的子对象。也就是说,为了保证这一点,在虚拟继承情况下,基类子对象的布局是不同于普通继承的。因此,它需要多出一个指向基类子对象的指针。

3.笔试,面试中常考的C++虚拟继承的知识点

第一种情况:      第二种情况:     第三种情况       第四种情况:
class a         class a        class a         class a
{          {           {            {
virtual void func();  virtual void func(); virtual void func();   virtual void func();
};            };          char x;          char x;
class b:public virtual a class b :public a   };            };
{            {           class b:public virtual a  class b:public a
virtual void foo();  virtual void foo();  {             {
};            };           virtual void foo();    virtual void foo();
}; char x; }; // 最后一行是我补的。

上面的代码网上拷贝的,凑合着看吧。

如果对这四种情况分别求sizeof(a),  sizeof(b)。结果是什么样的呢?下面是输出结果(懒得验证了,直接看vc的结果吧):

如果对这四种情况分别求sizeof(a),  sizeof(b)。结果是什么样的呢?下面是输出结果:
第一种:4,12 
第二种:4,4
第三种:8,16
第四种:8,8

原因:

因为每个存在虚函数的类都要有一个4字节的指针指向自己的虚函数表,所以每种情况的类a所占的字节数应该是没有什么问题的,那么类b的字节数怎么算呢?看“第一种”和“第三种”情况采用的是虚继承,那么这时候就要有这样的一个指针vptr_b_a,这个指针叫虚类指针,也是四个字节;还要包括类a的字节数,所以类b的字节数就求出来了。

4.c++重载、覆盖、隐藏的区别和执行方式

(重载隐藏等知识点也可以参考我这篇文章:http://www.cnblogs.com/charlesblc/p/6133605.html

既然说到了继承的问题,那么不妨讨论一下经常提到的重载,覆盖和隐藏
4.1成员函数被重载的特征
(1)相同的范围(在同一个类中); 
(2)函数名字相同; 
(3)参数不同; 
(4)virtual 关键字可有可无。

4.2“覆盖”是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类); 
(2)函数名字相同; 
(3)参数相同; 
(4)基类函数必须有virtual 关键字。

4.3“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,特征是:

(1)如果派生类的函数与基类的函数同名,但是参数不同,此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 
(2)如果派生类的函数与基类的函数同名,但是参数相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

上面隐藏,其实指的是子类指针或者引用,在调用函数的时候,只会看子类自己的函数来选择,而不会管父类中有没有合适的函数。更具体的讨论,还是看这篇文章吧:http://www.cnblogs.com/charlesblc/p/6133605.html

C++中的虚继承 & 重载隐藏覆盖的讨论的更多相关文章

  1. Delphi中静态方法重载还是覆盖的讨论

    Delphi中静态方法重载还是覆盖的讨论 新人学习Delphi的时候,容易搞不懂的一个问题,当子类方法和基类方法同名,并且参数也一样的时候,叫做什么呢?是覆盖,还是重载呢? 答案是隐藏父类方法. 一般 ...

  2. (C/C++学习)5.C++中的虚继承-虚函数-多态解析

    说明:在C++学习的过程中,虚继承-虚函数经常是初学者容易产生误解的两个概念,它们与C++中多态形成的关系,也是很多初学者经常产生困惑的地方,这篇文章将依次分别对三者进行解析,并讲述其之间的联系与不同 ...

  3. Java继承方法隐藏(覆盖)

    方法隐藏 一个类从其超类继承所有非私有静态方法.在子类中重新定义继承的静态方法称为方法隐藏.子类中的重定义静态方法隐藏其超类的静态方法.在类中重定义非静态方法称为方法覆盖.关于方法隐藏的重定义方法(名 ...

  4. C++中的重载隐藏覆盖&&JAVA中的重载覆盖&&多态

    class 类继承默认是private, struct 默认继承是public C++中的隐藏: 只要派生类中出现和基类一样的函数名,基类中的函数就会被派生类中的函数给隐藏(如果派生类和基类中的函数名 ...

  5. C++中虚继承派生类构造函数的正确写法

    最近工作中某个软件功能出现了退化,追查下来发现是一个类的成员变量没有被正确的初始化.这个问题与C++存在虚继承的情况下派生类构造函数的写法有关.在此说明一下错误发生的原因,希望对更多的人有帮助. 我们 ...

  6. 多重继承,虚继承,MI继承中虚继承中构造函数的调用情况

    先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include < ...

  7. C++对象模型:单继承,多继承,虚继承

    什么是对象模型 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分.对于各种支持的底层实现机制. 类中成员分类 数据成员分为静态和非静态,成员函数有静态非静态以及虚函数 clas ...

  8. 【转】C++中的虚函数的实现

    转自:http://blog.csdn.net/haoel/article/details/1948051 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(V ...

  9. C++对象模型:单继承,多继承,虚继承,菱形虚继承,及其内存布局图

    C++目前使用的对象模型: 此模型下,nonstatic数据成员被置于每一个类的对象中,而static数据成员则被置于类对象之外,static和nonstatic函数也都放在类对象之外(通过函数指针指 ...

随机推荐

  1. Mix and Build(简单DP)

    Mix and Build Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3936 Accepted: 1203 Case Ti ...

  2. Uva 1103 古代象形文字

    题目链接:http://vjudge.net/contest/140550#problem/B 紫书P163. 1.根据16进制图转成2进制图. 每个点dfs一下,马上就把最外围的连通分量编号求出来了 ...

  3. thinkphp 删除多条记录

    删除id为123456的记录 $ids=array(1,2,3,4,5,6);$maps["id"] = array("in",$ids);$this-> ...

  4. 如何在linux下查看gpu信息

    ~$ lspci | grep -i vga01:00.0 VGA compatible controller: NVIDIA Corporation GF119 [GeForce GT 610] ( ...

  5. Mysql 升级到 5.6 后插入语句时间字段报错:Incorrect datetime value: '' for column 'createtime'

    今天部署服务器项目运行,当遇见有时间数据对象的插入和更新操作的时候,就报错,如下: Caused by: com.mysql.jdbc.MysqlDataTruncation: Data trunca ...

  6. NSIS学习记录の----NSIS多语言安装以及详解

    NSIS多语言安装,很多教程提供了详细的代码,但是代码中某些语句的含义我还是不很明白,作为一个吃螃蟹的人,我做一个解释,避免很多小伙伴和我哟U一样的误区,以下结论都是自己根据实践得来,若发现理解错误, ...

  7. javaScript动态参数

    javaScript是动态语言,那么动态参数的话也是与生俱来的, 在去取javaScript得参数用的是Arguments这个属性,去取 <script type="text/java ...

  8. SGU 105 div.3 找规律

    There is sequence 1, 12, 123, 1234, ..., 12345678910, ... . Given first N elements of that sequence. ...

  9. Swift语法总结补充(一)

    Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1. 可选类型是一种类型,String?就是Optional<String>,所以函数参数也可以声明为它2 ...

  10. 修改客户端Webbrowser对应IE版本步骤

    制作注册表文件的过程 1,” HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InternetExplorer\MAIN\ FeatureControl\FEATURE_B ...