在面向对象的编程过程中,经常使用多态,以便得到不同的实现。
不使用virtual关键字
class Super
{
public:
/*Super():id(0),str("hello")
{
}*/
void DoSth()
{
cout<<"Super-DoSth"<<endl;
//cout<<str<<endl;
}
/*~Super()
{
}*/
//private:
//int id;//4bytes
//string str;//32bytes
};
Super类的布局:
+---
+---
Sub类继承Super,重写DoSth函数。
class Sub : public Super
{
public:
void DoSth()
{
cout<<"Sub-DoSth"<<endl;
}
};
Sub类的布局:
class Sub size(1):
+---
| +--- (base class Super)
| +---
+---
//函数的调用:
Super super;
((Sub&)super).DoSth();//输出Sub-DoSth
通过向子类的类型的转换,实现调用子类的函数。
使用virtual关键字
把Super的DoSth()前加virtual,如下:
virtual void DoSth()
那么Super类的布局变为:
class Super size(4):
+---
0 | {vfptr}
+---
Super::$vftable@:
| &Super_meta
| 0
0 | &Super::DoSth
Super::DoSth this adjustor: 0
Sub类的布局变为:
class Sub size(4):
+---
| +--- (base class Super)
0 | | {vfptr}
| +---
+---
Sub::$vftable@:
| &Sub_meta
| 0
0 | &Sub::DoSth
Sub::DoSth this adjustor: 0
//函数的调用:
Super super;
((Sub&)super).DoSth();//输出Super-DoSth
通过以下方式实现调用子类的方法:
Sub sub;
Super* pSuper=⊂
pSuper->DoSth();//输出Sub-DoSth
总结:在设计类的时候,考虑到函数多种实现的时候,不一定非要在函数前面加vritual,当加virtual的时候会有虚函数表,会增加开销。