c++ 虚继承与继承的差异
来源:互联网 发布:男生保养脸部皮肤知乎 编辑:程序博客网 时间:2024/04/28 14:30
前面一篇文章,说明了在C++ 虚继承对基类构造函数调用顺序的影响。经过仔细推敲,发现没有彻底说清楚虚继承与普通继承之间的关系。所以用下面的文字再说明一下。
首先,重复一下虚拟继承与普通继承的区别有:
假设derived 继承自base类,那么derived与base是一种“is a”的关系,即derived类是base类,而反之错误;
假设derived 虚继承自base类,那么derivd与base是一种“has a”的关系,即derived类有一个指向base类的vptr。
因此虚继承可以认为不是一种继承关系,而可以认为是一种组合的关系。因为虚继承有着“继承”两个关键字,那么大部分人都认为虚继承与普通继承的用法没什么太大的不同。由此用在继承体系中,这种将虚继承认为是普通继承的危害更佳大。下面先用一个例子来说明问题:
class base{public: base(){cout<<"base::base()!"<<endl;} void printBase(){cout<<"base::printBase()!"<<endl;}};class derived:public base{public: derived(){cout<<"derived::derived()!"<<endl;} void printDerived(){cout<<"derived::printDerived()!"<<endl;}};
上面是普通继承实现,在实际应用中,我们可以使用下面的代码进行类型转换:
int main(int argc, const char * argv[]){ derived oo; base oo1(static_cast<base>(oo)); oo1.printBase(); derived oo2 = static_cast<derived&>(oo1); oo2.printDerived(); return 0;}编译无错误,而且会得出正确的结果。其结果为:
base::base()!
derived::derived()!
base::printBase()!
derived::printDerived()!
而将上面的普通继承变成虚拟继承,如下代码:
class base1{public: base1(){cout<<"base::base()!"<<endl;} void printBase(){cout<<"base::printBase()!"<<endl;}};class derived1:virtual public base1{public: derived1(){cout<<"derived::derived()!"<<endl;} void printDerived(){cout<<"derived::printDerived()!"<<endl;}};int main(int argc, const char * argv[]){ derived1 oo; base1 oo1(static_cast<base1>(oo)); oo1.printBase(); derived1 oo2 = static_cast<derived1&>(oo1); oo2.printDerived(); return 0;}
编译上面的代码,提示如下:
可以看到不能将基类通过static_cast转换为继承类。我们知道c++提供的强制转换函数static_cast对于继承体系中的类对象的转换一般是可行的。那么这里为什么就不可以了呢?还是需要从虚拟继承的内部实现来说明问题。
virtual base class的原始模型是在class object中为每一个有关联的virtual base class加上一个指针vptr,该指针指向virtual基类表。有的编译器是在继承类已存在的virtual table直接扩充导入一个virtual base class table。不管怎么样由于虚继承已完全破坏了继承体系,不能按照平常的继承体系来进行类型转换。
不管怎么样,虚继承在类型转换是一定要十分注意。不要轻易使用虚继承,更不要在虚继承的基础上进行类型转换,切记切记!
- c++ 虚继承与继承的差异
- C++ 虚继承与继承的差异
- c++ 虚继承与继承的差异
- c++ 虚继承与继承的差异
- c++ 虚继承与继承的差异
- C++虚继承(八) --- 虚继承与继承的差异
- C++ __虚继承与继承的差异
- JScript与SpiderMonkey对继承成员可见性的差异
- 继承与虚继承
- 继承与虚继承
- (C++)继承、菱形继承和虚继承的那些事儿
- c++虚继承与继承的区别
- 类的一般继承与虚继承
- c++的继承与虚继承
- 【C++】菱形继承与虚拟菱形继承的对比分析
- 11 继承,多重继承与虚继承
- C++_Primer_chapter17 3.多重继承与虚继承
- C++: 继承与派生
- 细说ASP.NET Forms身份认证
- sqlserver2008 事务日志物理文件过大无法缩小 分析
- as3中,判断是中文、英语、数字
- 最新flash player 11.4.402.278在Win7 + Firefox环境下无法检测到摄像头被占用
- VS2008 error C2664的解决 字符编码
- c++ 虚继承与继承的差异
- UITapGestureRecognizer 的用法
- poco库学习笔记(7) Poco::Any
- unicode环境下用CFile读取txt的若干疑惑,该如何处理
- SQL网上一些浏览(5)
- C#打开网址的方法
- YUV420图像格式
- 宏发41F-1Z-C2接线
- 开源中最好的Web开发的资源