码迷,mamicode.com
首页 > 其他好文 > 详细

虚函数——虚表总结

时间:2016-04-19 20:14:01      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:public   虚函数   虚表   


非虚拟继承

带虚函数的类

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

int main()

{

Base b;

b._data1 = 0x01;

return 0;

}

 

Base类没有显式定义自己的构造函数,此时编译器会和成默认的构造函数,

技术分享

合成的构造函数中主要完成在对象头4个字节中填写虚表地址:

技术分享

Base类对象最后的模型如下:

技术分享

注意:同一个类的对象共用同一个虚表

技术分享

从上述的结果中可以得到印证。

【单继承(派生类中没有虚函数覆盖)

class Base

{

public:

virtual void FunTest1()

{cout<<"Base::FunTest1()"<<endl;}

 

virtual void FunTest2()

{cout<<"Base::FunTest2()"<<endl;}

           int _data1;

};

 

class Derive:public Base

{

public:

virtual void FunTest3()

{cout<<"Derive::FunTest3()"<<endl;}

 

virtual void FunTest4()

{cout<<"Derive::FunTest4()"<<endl;}

 int _data2;

};

 

// 打印虚表

typedef void (*VtbFun)();

void PrintVtable()

{

cout<<"Derive类的虚函数表:"<<endl;

Derive d1;

d1._data1 = 0x01;

d1._data2 = 0x02;

 

int* pVTable = (int*)*(int*)&d1;

VtbFun FunTest = (VtbFun)*pVTable;

while(NULL != FunTest)

{

FunTest();

cout<<(int*)FunTest<<endl;

pVTable += 1;

FunTest = (VtbFun)*pVTable;

}

 

cout<<"虚表结束:"<<endl;

}

 

int main()

{

Base b1;

Derive d1;

return 0;

}

 

按照如上分析的顺序,探索下单继承下派生类对象模型以及虚表

首先看看编译器为派生类合成的缺省构造函数:

技术分享

派生类构造函数中进行了如下事情:

技术分享

Derive d1;

d1._data1 = 0x01;

d1._data2 = 0x02;

派生类最后的对象模型为:

技术分享

【单继承(派生类中有虚函数覆盖)

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Derive:public Base

{

public:

virtual void FunTest1()

{

cout<<"Derive::FunTest1()"<<endl;

}

 

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<<endl;

}

 

virtual void FunTest4()

{

cout<<"Derive::FunTest4()"<<endl;

}

int _data2;

};

 

int main()

{

PrintVtable();

return 0;

}

 

派生类对象模型及虚表建议规则:

技术分享

【多继承(派生类不覆盖基类虚函数)

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Base1

{

public:

virtual void FunTest3()

{

cout<<"Base1::FunTest3()"<<endl;

}

 

virtual void FunTest4()

{

cout<<"Base1::FunTest4()"<<endl;

}

 

int _data2;

};

 

class Derive:public Base, public Base1

{

public:

virtual void FunTest5()

{

cout<<"Derive::FunTest5()"<<endl;

}

 

int _data3;

};

 

int main()

{

cout<<"sizeof(Derive) = "<<sizeof(Derive)<<endl;

Derive d;

d._data1 = 0x01;

d._data2 = 0x02;

d._data3 = 0x03;

PrintVtable();

return 0;

}

 

同样:看看编译器合成的派生类的对象做了什么工作

技术分享

观察下派生类的对象模型和虚表的建立过程

技术分享

从上面的结果可以看出,Derive类自己特有的虚函数直接添加在Base类对应虚函数表最后的位置,大家可将BaseBase1的顺序交换验证下。

 

【多继承(派生类覆盖基类虚函数)

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Base1

{

public:

virtual void FunTest3()

{

cout<<"Base1::FunTest3()"<<endl;

}

 

virtual void FunTest4()

{

cout<<"Base1::FunTest4()"<<endl;

}

 

int _data2;

};

 

// 这次将继承列表中BaseBase1的位置互换

class Derive:public Base1, public Base

{

public:

virtual void FunTest1()

{

cout<<"Derive::FunTest1()"<<endl;

}

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<<endl;

}

virtual void FunTest5()

{

cout<<"Derive::FunTest5()"<<endl;

}

 

int _data3;

};

 

int main()

{

           PrintVtable();

return 0;

}

 

此时派生类的对象模型和虚表的结构:

技术分享

虚拟继承

// 没有虚函数覆盖,但派生类有自己的虚函数

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<<endl;

}

 

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<<endl;

}

 

int _data1;

};

 

class Derive:virtual public Base

{

public:

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<<endl;

}

virtual void FunTest4()

{

cout<<"Derive::FunTest4()"<<endl;

}

 

int _data2;

};

 

虚拟继承编译器为派生类合成的默认构造函数分析

技术分享

编译器为派生类合成的默认构造函数任务分析:

技术分享技术分享

虚拟继承派生类对象模型分析

技术分享

本文出自 “11275984” 博客,请务必保留此出处http://11285984.blog.51cto.com/11275984/1765455

虚函数——虚表总结

标签:public   虚函数   虚表   

原文地址:http://11285984.blog.51cto.com/11275984/1765455

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!