虚拟继承、虚函数学习总结
一、虚函数。
其实是比较简单的,它的存在就是为了给子类继承,并且提供多个接口,所谓多个接口,就是多态性,它的主要特点就是父类的指针可以指向子类的对象,这样的话,在继承上会有好处。例如,某个父类有多个子类,在不知道会调用哪一个子类对象的情况下,可以定义一个父类的指针
f
,这样就实现了所谓的“接口”功能,在知道了要使用哪一个子类的时候,就直接把父类的指针
f
指向那个子类的对象,以后的操作都是采用父类的指针
f
,这样显然就有优点了,可以把对子类的操作封装起来,跟它使用哪一个子类没有关系了,因为在被封装起来的操作里面操作的对象是父类的指针
f
,然后这些被封装的操作就提供了一个“接口”,要用哪一个类的对象,就把那一个类对象的地址给父类的指针
f
。
二、虚函数非虚拟继承
CSDN
的博客上有一篇文章《
C++
虚函数表解析》,作者:陈皓
网址:
http://blog.csdn.net/haoel/archive/2007/12/18/1948051.aspx
说的是虚函数在内存中的格局,讲得很好理解。通过
vs2005
调试查看内存也是一样的。就是虚函数表。
三、虚拟继承。
CSDN
的博客上有一篇文章《
C++
对象内存布局》,作者:陈皓
网址
http://blog.csdn.net/haoel/archive/2008/10/15/3081328.aspx
里面讲述了
c++
虚函数的各种继承的内存布局,讲得非常详细,大部分的内容都很容易看懂,但是在
讲解虚拟继承上还有一点不足,就是虚函数的虚拟继承漏了一点内容,虚基函数表(vbtbl)
的相关内容。
另一篇文章写得很好,也是CSDN
博客上的,《
c++
虚继承对象的内存布局
》
网址:
http://blog.csdn.net/BlueDog/archive/2009/10/22/4711169.aspx
在《
C++
对象内存布局》有一个名词叫做“钻石型虚拟多重继承”,之前不知道该怎么称呼这种继承,画成图,它们的形状就像棱形,一个基类产生两个子类,两个子类又同时被另一个“孙类”虚拟继承,最简单的虚拟继承就是这样子。
1、
没有涉及虚函数的虚拟继承。如果不管内部如何实现,简单的说就是“孙类”只拷贝一次基类,如果涉及到内存布局,那就必须通过
debug
,查看执行时的内存,
《
c++
虚继承对象的内存布局
》说到了这一点。通过内存查看“孙类”对象的地址,这个地址就相当于有虚函数的虚拟继承的“
Virtual Base Class Table
”简称“
VBTBL
”,当然名称可能有点问题,因为它只是包含用来寻找虚基类表的偏移值,而不是虚基类表的指针。在没有虚函数的情况下,它保存的内容同样有两项(因为只有一个基类),第一项为
0
,因为没有虚函数,第二项为本地址相对于基类的偏移值。从“孙类”的内存中发现,基类的内容放在在最后面,这也跟有虚函数的时候一样。可能是为了跟有虚函数的时候统一,格式是一样的,这样的话,在没有虚函数的时候,有些是没有用的,如
B
子类也有个类似于“
VBTBL
”的东西,如果没有理解错的话,它应该是没用的,访问基类的时候用不着它。在查看内存的时候还发现了一些现象,内存里面没有函数的地址,只有变量空间,这个大概就是非虚函数跟虚函数的不同吧。通过查看内存可以很好的理解底层的东西。
2、
含有虚函数的虚拟继承。这就涉及到了虚函数表、虚基类、
VBTBL
。
《
c++
虚继承对象的内存布局
》里面说得很详细,那个“孙”类对象的内存结构图看起来非常的明确,我在
vs2005
里面查看,完全一样。
3、
总结:有虚拟继承的“孙”类的对象的内存格局是这样的,被虚拟继承的基类放在最后,子类按顺序放在基类的前面。子类的对象的内存格局,基类也是放在最后。虚拟继承的每一个类都有“
VBTBL
”之类的东西。
分享到:
相关推荐
本章介绍了C++中的继承和多态性概念,包括基类与派生类的关系、继承的访问控制、覆盖方法、构造函数、多态性基础、虚函数、纯虚函数以及抽象类的概念。此外,还讨论了多重继承及其解决方案——虚拟继承,以应对复杂...
在C++中,虚拟继承(virtual inheritance)是一种解决多重继承中...在没有虚函数的情况下,虚拟继承对成员变量的访问效率影响不大,但在有虚函数时,通过虚基类指针访问成员会涉及vtable和动态解析,这可能会降低性能。
虚拟继承是在多重继承中引入的一个概念,它可以解决“菱形问题”,即当一个类同时继承了具有相同成员的两个父类时,通过虚拟继承可以确保只有一个副本。 3. 带有纯虚函数的类被称为抽象类。抽象类不能被实例化,...
3. **类设计**:涵盖了访问控制、继承、多态和接口设计,提倡使用protected而非private继承,以及如何利用虚函数和纯虚函数实现多态性。 4. **模板与泛型编程**:介绍了模板的使用技巧,包括模板元编程和STL...
C++通过虚函数和纯虚函数实现多态,子类可以重写基类的虚函数,实现功能的扩展。 11. **静态成员**:静态成员属于类,而非对象,所有对象共享同一份静态成员。静态成员函数不能访问非静态成员,但可以直接调用其他...
1. **(a)** `Final`类对象的构造函数调用顺序是:首先调用`Class`的构造函数,接着调用`Derived1`和`Derived2`的构造函数(由于使用了虚拟继承,避免了二义性),然后是`MI`的构造函数,最后是`Final`的构造函数。...
- **添加虚函数** 会导致类的大小增加,因为编译器会自动为每个包含虚函数的类添加一个指向虚函数表的指针。在32位系统中,这个指针通常是4字节。 **正确答案:** b. 添加构造函数后,结果为1。c. 添加虚函数后,...
TSprite类继承自TPersistent,它提供了用于定义图形对象属性和行为的框架。通过深入分析TSprite类的源代码,开发者能够掌握如何创建和管理游戏中的精灵,了解其属性、方法和事件处理机制。 TSprite精灵基类具备私有...
13.3.Z Intel 80x86 13.3.3 IBM RS/6000 13.3.4 MIPS R3000 13.4 4.3BSBSD 实例研究 13.4.1 物理内存 13.4.2 地址空间 13.4.3 页面在哪里 13.4.4 交换区 13.5 4.3BSD 内存管理操作 13.5.1 创建进程 13.5.2 页面失效...