C++之虚函数继承和虚继承
来源:互联网 发布:java io深入理解 编辑:程序博客网 时间:2024/05/22 00:42
平台:win7+VS2010
虚函数继承
虚函数是实现多态,异质列表的强大工具。主要原理是使用基类指针调用不同派生类的函数,使得同一函数可以有不同的实现效果。
PS:因为派生类指针一般长于基类指针,因此不建议使用派生类指针指向基类对象,否则可能会出现意想不到的错误。类似于类型转换时,长数据可以转换成短数据,但需要显示强制类型转换,而且长数据变成短数据可能造成数据丢失等错误。
#include <iostream>using namespace std;class Base{public:virtual void fb(){ cout<<"Base::fb"<<endl;} virtual void f(){} };class Derive:public Base{public:void fb(){ cout<<"Derive::fb"<<endl;} virtual void fd(){} };int main(){Derive d;Base *p = &d;p->fb();d.fb();return 0;}
Base类的fb()函数不是虚函数时,运行结果为:
Base::fb
Derive::fb
Base类的fb()函数是虚函数时,运行结果为:
Derive::fb
Derive::fb
派生类继承了基类的虚函数表,但是和基类的虚函数表的地址不同,当派生类覆盖了基类中的虚函数时,这个虚函数在虚函数表中将替代为派生类的训函数地址,没有重写的虚函数仍保留基类的虚函数地址。
所以说,
非虚函数继承中,实现的是函数的重载(this指针不同),即在Base类中void fb()实际上是void fb(Base * const this ),而在Derive类中void fb()实际上是void fb( Derive * const this)。
虚函数继承中,实现的是函数的覆盖,Derive的fb()函数会取代Base 的fb()函数在虚表中的位置,从而实现基类指针调用子类函数实现版本的效果。
虚继承
虚继承是多继承中,为了解决一个类间接地多次继承一个基类而造成空间浪费和与设计模型不同的问题,而打的一个补丁。应用虚继承,多次被继承的基类数据在派生类中只有一份数据而不是多份。
PS:一般不建议让一个类继承多个类,类树会比较复杂,实现和调试也比较复杂。
虚继承类的构造函数、析构函数调用顺序如下:
#include <iostream>using namespace std;class A{public:A(){cout<<"create class A"<<endl;}~A(){cout<<"drop class A"<<endl;}};class B:public virtual A{public:B(){cout<<"create class B"<<endl;}~B(){cout<<"drop class B"<<endl;}};class C:public virtual A{public:C(){cout<<"create class C"<<endl;}~C(){cout<<"drop class C"<<endl;}}; class D:public virtual C,public virtual B{public:D(){cout<<"create class D"<<endl;}~D(){cout<<"drop class D"<<endl;}}; int main(){D d;return 0;}运行结果为:
create class A
create class C
create class B
create class D
drop class D
drop class B
drop class C
drop class A
虚继承不同于一般继承,会生成多一个指向父类数据的指针。如下图:
验证如下:
#include <iostream>using namespace std;class A{virtual void fa();};class B:public virtual A{virtual void fb();};class C:public virtual A{virtual void fc();}; class D:public virtual C,public virtual B{virtual void fd();}; class E:public virtual B{virtual void fe();};class F:public virtual E{virtual void ff();};int main(){cout<<sizeof(A)<<endl;cout<<sizeof(B)<<endl;cout<<sizeof(C)<<endl;cout<<sizeof(D)<<endl;cout<<sizeof(E)<<endl;cout<<sizeof(F)<<endl;return 0;}运行结果为:
4
12
12
28
20
28
- C++之虚函数继承和虚继承
- 继承和虚函数
- C++之虚函数和多重继承
- 虚函数继承和虚继承
- 虚继承和虚函数继承
- 虚继承和虚函数继承
- 虚继承和虚函数继承
- 继承----有关虚函数和虚拟继承
- C++【多重继承和虚继承】
- (C++)继承、菱形继承和虚继承的那些事儿
- C++,继承、虚函数解惑!
- C++,继承、虚函数解惑!
- C++继承之钻石继承和虚继承
- [C/C++]继承、多态和虚函数整理
- 虚继承和虚函数
- 虚函数和虚继承
- 继承和纯虚函数
- 多重继承和虚函数
- 使用svn:ignore属性忽略某些文件
- 实现 iframe 子页面调用父页面中的js方法
- (八)-实现新闻页面
- C++中指针和引用的区别
- 如何在JavaScript里防止事件函数的高频触发和调用
- C++之虚函数继承和虚继承
- patch和diff的用法
- 单例模式
- IntelliJ IDEA使用笔记
- linux修改mac
- [LCA][dfs序]BZOJ 2819: Nim
- AlarmManager的使用与几个获取时间的操作
- window.createPopup()用法以及短消息提示框代码
- C 语言中的一维数组与指针