【探索】VS下实现虚继承的方法-2
来源:互联网 发布:蚌埠学院网络教学平台 编辑:程序博客网 时间:2024/05/24 05:25
上篇讲到VS下实现虚继承中成员变量的二义性与数据冗余的解决方案是怎样的,今天我们来看看虚继承的成员函数会如何。
首先,虚继承会不会重写成员函数?我们看一看如下代码:
#include<iostream>using namespace std;class A{public:void fun(){cout << "this is fun of A"<<endl;}};class B1 : public A{public:void fun(){cout << "this is fun of B1" << endl;}};class B2 : public A{public:void fun(){cout << "this is fun of B2" << endl;}};class C : public B1, public B2{public:void fun(){cout << "this is fun of C" << endl;}};int main(){C c;c.fun();c.B1::fun();c.B2::fun();c.A::fun();//编译不通过,对象不存在}
这里,主函数中哪条指令编译不过去呢,明显是最后一条,因为调用对象不明确,c继承了b1,b2,b1,b2中都含有A,c中不直接含有对象a,所以编译不同过的原因是,系统无法识别我们调用的是b2还是b1中的a,这在某种程度上而言,也是二义性的表现形式,在c中,我们并不需要知道A,B1,B2,的fun(),秩序要知道C中的fun(),这里我们用虚函数重写,使得fun()重写,这样我们便可以使得C从各个域中的fun()的表现形式变为一样吗?我们来看看虚函数重写的结果:
答案是不可以的,虚函数重写,仅仅是将成员函数覆盖掉,并没有使派生类中调用基类中的成员函数“销毁”。派生类仍可以通过域访问到基类中的成员函数。那如果我们使用虚继承呢?
答案还是不可以的:
打开监视窗口,我们发现,C中包含3个虚表指针,每一个虚表指针都是存的是c::fun()的地址,但是还是可以通过域访问到不同的fun(),如果我们把A中添加一成员变量,通过内存观察,(这与我们上一篇讲到的一样,为了解决数据冗余,虚继承使得菱形继承中的超类得成员变量仅有一份存储在派生类中,两个基类会以指针偏移的方式访问同一个数据,在VS2013下,并没有存储真正的基类的成员变量,这是一种优化),在以前vs版本,可能派生类还能保存基类中成员变量的数据。而成员函数,并不是存储在对象中的内容,故通过域访问,还是可以修改的。
本文出自 “pawnsir的IT之路” 博客,请务必保留此出处http://10743407.blog.51cto.com/10733407/1750438
- 【探索】VS下实现虚继承的方法-2
- 【探索】VS下虚继承实现的方法-1
- 虚方法的调用是怎么实现的(单继承VS多继承)
- java下自定义read方法的实现并可以继承
- 探索NDIS HOOK新的实现方法(2)
- 探索NDIS HOOK新的实现方法(2)
- 探索NDIS HOOK新的实现方法(2)
- 探索NDIS HOOK新的实现方法
- javascript实现继承的方法
- js的继承实现方法
- js实现继承的方法
- JavaScript实现继承的方法
- Javascript实现继承的方法
- 实现触摸的类的继承方法有2种
- VS 2003 下调用MSXML的方法
- LTP在vs下的配置方法
- 深入探索c++虚继承
- VS或C#或.NET环境下的发送邮件实现方法
- 15种最佳系统日志优化实践
- C语言中的函数指针
- 【总结】C++静态成员函数及测试用例
- 解决 NSObjCRuntime的问题
- 【探索】VS下虚继承实现的方法-1
- 【探索】VS下实现虚继承的方法-2
- 关于mybatis的collection映射问题
- 【代码】模板实现双向链表的去重、拼接、合并、排序
- 基于hadoop与spark的大数据分析实战——第二章、Spark部署与安装
- 【干货】C++通过模板特化实现类型萃取实例--实现区分基本类型与自定义类型的memcpy
- 【代码】模板实现动态线性表(无类型萃取)
- 【技巧】通过适配器模式完成栈的数据结构
- 【代码】模板动态线性表&类型萃取
- 【干货】share智能指针的模拟实现