关于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;
虚拟继承在一般的应用中很少用到,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用,而一旦离开了多重继承,虚拟继承就完全失去了存在的必要因为这样只会降低效率和占用更多的空间。
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();
}; };
如果对这四种情况分别求sizeof(a), sizeof(b)。结果是什么样的呢?下面是输出结果:(在vc6.0中运行)
第一种:4,12
第二种:4,4
第三种:8,16
第四种:8,8
想想这是为什么呢?
因为每个存在虚函数的类都要有一个4字节的指针指向自己的虚函数表,所以每种情况的类a所占的字节数应该是没有什么问题的,那么类b的字节数怎么算呢?看“第一种”和“第三种”情况采用的是虚继承,那么这时候就要有这样的一个指针vptr_b_a,这个指针叫虚类指针,也是四个字节;还要包括类a的字节数,所以类b的字节数就求出来了。而“第二种”和“第四种”情况则不包括vptr_b_a这个指针,这回应该木有问题了吧。
4.c++重载、覆盖、隐藏的区别和执行方式
既然说到了继承的问题,那么不妨讨论一下经常提到的重载,覆盖和隐藏
4.1成员函数被重载的特征
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
4.2“覆盖”是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
4.3“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,特征是:
(1)如果派生类的函数与基类的函数同名,但是参数不同,此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,但是参数相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
小结:说白了就是如果派生类和基类的函数名和参数都相同,属于覆盖,这是可以理解的吧,完全一样当然要覆盖了;如果只是函数名相同,参数并不相同,则属于隐藏。
4.4 三种情况怎么执行:
4.4.1 重载:看参数。
4.4.2 隐藏:用什么就调用什么。
4.4.3 覆盖:调用派生类。
学习中的一点总结,欢迎拍砖哦^^
关于C++中的虚拟继承的一些总结的更多相关文章
- 从汇编看c++中的虚拟继承及内存布局(二)
下面是c++源码: class Top {//虚基类 public: int i; Top(int ii) { i = ii; } virtual int getTop() { cout <&l ...
- C++中的虚继承 & 重载隐藏覆盖的讨论
虚继承这个东西用的真不多.估计也就是面试的时候会用到吧.. 可以看这篇文章:<关于C++中的虚拟继承的一些总结> 虚拟基类是为解决多重继承而出现的. 如:类D继承自类B1.B2,而类B1. ...
- c++面试常用知识(sizeof计算类的大小,虚拟继承,重载,隐藏,覆盖)
一. sizeof计算结构体 注:本机机器字长为64位 1.最普通的类和普通的继承 #include<iostream> using namespace std; class Parent ...
- C++ 虚拟继承
1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念.虚拟基类是为解决多重继承而出现的.如:类D继承自类B1.B2,而类B1.B2都继 承自类A,因此在类D中两次出现类A中的变量和函数.为了节省内 ...
- 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。
本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...
- 关于虚拟继承类的大小问题探索,VC++ 和 G++ 结果是有区别的
昨天笔试遇到个 关于类占用的空间大小的问题,以前没怎么重视,回来做个试验,还真发现了问题,以后各位笔试考官门,出题时请注明是用什么编译器. vc6/vc8 cl 和 Dev-C 的g++ 来做的测试: ...
- c++,为什么要引入虚拟继承
虚拟基类是为解决多重继承而出现的. 以下面的一个例子为例: #include <iostream.h> #include <memory.h> class CA { i ...
- C++中的类继承(4)继承种类之单继承&多继承&菱形继承
单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可 ...
- C++多重继承与虚拟继承
本文只是粗浅讨论一下C++中的多重继承和虚拟继承. 多重继承中的构造函数和析构函数调用次序 我们先来看一下简单的例子: #include <iostream> using namespac ...
随机推荐
- Java中RMI框架
嘎嘎,有空写……先记着了
- angular2 学习笔记 (Typescript)
1.接口奇葩验证 interface Abc { name : string } function abc(obj : Abc) { } let ttc = { name: "adad&qu ...
- 如何打开mo文件并修改 PoEdit
mo文件是被编译了的文件,一般在汉化的时候会用到. 比如我想修改phpmyadmin 的界面信息,就需要修改phpmyadmin.mo的文件内容. 可是用编辑器editplus或者Sublime 2打 ...
- Linux下的memset函数
函数原型 void *memset(void *s, int c, size_t n); 函数功能 将以s为首的存储空间前n字节空间全部替换为参数c指定的数据. 返回值 更新后的首地址s. 头文件 # ...
- Matlab:拟合(1)
拟合练习: function f = curvefun(x, tdata) f = (x()*x()*x()) / (x()-x()) * ( exp(-x()*tdata)/(x()-x()) + ...
- iOS音频处理
ios音频处理 1. iOS底层音频处理技术(带源代码) http://www.cocoachina.com/ios/20111122/3563.html 2.ios 音频入门 http://blog ...
- HTTP学习笔记7-消息报头
41,消息报头-实体报头 请求和响应消息可以传送一个实体.一个实体由实体报头域和实体正文组成,在大多数情况下,实体正文就是请求消息中的请求正文或者响应消息中的响应正文.但是在发送时,并不是说实体报头域 ...
- hibernate ThreadLocal
代码 package com.pb.hibernate.util; import org.hibernate.HibernateException; import org.hibernate.Sess ...
- motan源码分析四:客户端调用服务
在第一章中,我们分析了服务的发布与注册,本章中将简单的分析一下客户端调用服务的代码及流程,本文将以spring加载的方式进行分析. 1.在DemoRpcClient类的main()方法中加载类: Ap ...
- Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON
I create a very simple website.when I run website from VS2012 ,website easily can get data from SQLS ...