欢迎来到天天文库
浏览记录
ID:49531155
大小:93.34 KB
页数:8页
时间:2020-03-02
《动态联编实现原理分析.doc》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、动态联编实现原理分析所谓动态联编,是指被调函数入口地址是在运行时、而不是在编译时决定的。C++语言利用动态联编来完成虚函数调用。C++标准并没有规定如何实现动态联编,但大多数的C++编译器都是通过虚指针(vptr)和虚函数表(vtable)来实现动态联编。基本的思路是:(1)为每一个包含虚函数的类建立一个虚函数表,虚函数表的每一个表项存放的是个虚函数在内存中的入口地址;(2)在该类的每个对象中设置一个指向虚函数表的指针,在调用虚函数时,先采用虚指针找到虚函数表,确定虚函数的入口地址在表中的位置,获取入口地址完成
2、调用。我们将从以下几个方面来考察动态联编的实现细节。1.虚指针(vptr)的存放位置虚指针是作为对象的一部分存放在对象的空间中。一个类只有一个虚函数表,因此类的所有对象中的虚指针都指向同一个地方。在不同的编译器中,虚指针在对象中的位置时不同的。两种典型的做法是:(1)在VisualC++中,虚指针位于对象的起始位置;(2)在GNUC++中,虚指针位于对象的尾部而不是头部。可通过下面的程序考察在VisualC++中,虚指针在对象中的位置。#includeusingnamespacestd;in
3、tglobalv;classNoVirtual{inti;public:voidfunc(){cout<<"novirtualfunction"<4、ut<<"sizeof(NoVirtual):"<(&n1);cout<<"first4bytesofn1:"<(&n2);cout<<"first4bytesofn2:"<5、p=reinterpret_cast(&h1);cout<<"first4bytesofh1:0x"<(&h2);cout<<"first4bytesofh2:0x"<6、员i,所以sizeof(NoVirtual)为4。类HaveVirtual包含虚函数,因此类HaveVirtual的对象不近要包含数据成员i,还要包含一个指向虚函数表的指针(大小为4B),所以sizeof(HaveVirtual)为8。(2)虚指针如果不在对象的头部,那么对象h1和对象h2的头4个字节(代表整型成员变量i)的值应该是3和4。而程序结果显示,类HaveVirtual的两个对象h1和h2的头4个字节的内容相同,这个值就是类HaveVirtual的虚函数表所在地址。2.虚函数表(vtable)的内部结7、构虚函数表是为拥有虚函数的类准备的。虚函数表中存放的是类的各个虚函数的入口地址。那么,可以思考以下几个问题:(1)虚函数的入口地址是按照什么顺序存放在虚函数表中的呢?(2)不同的类(比如说父类和子类)是否可以共享同一张虚函数表的呢?(3)虚函数表是一个类的对象共享,还是一个对象就拥有一个虚函数表?(4)多重继承的情况下,派生类有多少个虚函数表呢?考察如下程序:#includeusingnamespacestd;#defineShowFuncAddress(function)_asm{8mo8、veax,function}_asm{movp,eax}cout<<"Addressof"#function":"<(pObj);
4、ut<<"sizeof(NoVirtual):"<(&n1);cout<<"first4bytesofn1:"<(&n2);cout<<"first4bytesofn2:"<5、p=reinterpret_cast(&h1);cout<<"first4bytesofh1:0x"<(&h2);cout<<"first4bytesofh2:0x"<6、员i,所以sizeof(NoVirtual)为4。类HaveVirtual包含虚函数,因此类HaveVirtual的对象不近要包含数据成员i,还要包含一个指向虚函数表的指针(大小为4B),所以sizeof(HaveVirtual)为8。(2)虚指针如果不在对象的头部,那么对象h1和对象h2的头4个字节(代表整型成员变量i)的值应该是3和4。而程序结果显示,类HaveVirtual的两个对象h1和h2的头4个字节的内容相同,这个值就是类HaveVirtual的虚函数表所在地址。2.虚函数表(vtable)的内部结7、构虚函数表是为拥有虚函数的类准备的。虚函数表中存放的是类的各个虚函数的入口地址。那么,可以思考以下几个问题:(1)虚函数的入口地址是按照什么顺序存放在虚函数表中的呢?(2)不同的类(比如说父类和子类)是否可以共享同一张虚函数表的呢?(3)虚函数表是一个类的对象共享,还是一个对象就拥有一个虚函数表?(4)多重继承的情况下,派生类有多少个虚函数表呢?考察如下程序:#includeusingnamespacestd;#defineShowFuncAddress(function)_asm{8mo8、veax,function}_asm{movp,eax}cout<<"Addressof"#function":"<(pObj);
(&n2);cout<<"first4bytesofn2:"<
5、p=reinterpret_cast(&h1);cout<<"first4bytesofh1:0x"<(&h2);cout<<"first4bytesofh2:0x"<6、员i,所以sizeof(NoVirtual)为4。类HaveVirtual包含虚函数,因此类HaveVirtual的对象不近要包含数据成员i,还要包含一个指向虚函数表的指针(大小为4B),所以sizeof(HaveVirtual)为8。(2)虚指针如果不在对象的头部,那么对象h1和对象h2的头4个字节(代表整型成员变量i)的值应该是3和4。而程序结果显示,类HaveVirtual的两个对象h1和h2的头4个字节的内容相同,这个值就是类HaveVirtual的虚函数表所在地址。2.虚函数表(vtable)的内部结7、构虚函数表是为拥有虚函数的类准备的。虚函数表中存放的是类的各个虚函数的入口地址。那么,可以思考以下几个问题:(1)虚函数的入口地址是按照什么顺序存放在虚函数表中的呢?(2)不同的类(比如说父类和子类)是否可以共享同一张虚函数表的呢?(3)虚函数表是一个类的对象共享,还是一个对象就拥有一个虚函数表?(4)多重继承的情况下,派生类有多少个虚函数表呢?考察如下程序:#includeusingnamespacestd;#defineShowFuncAddress(function)_asm{8mo8、veax,function}_asm{movp,eax}cout<<"Addressof"#function":"<(pObj);
6、员i,所以sizeof(NoVirtual)为4。类HaveVirtual包含虚函数,因此类HaveVirtual的对象不近要包含数据成员i,还要包含一个指向虚函数表的指针(大小为4B),所以sizeof(HaveVirtual)为8。(2)虚指针如果不在对象的头部,那么对象h1和对象h2的头4个字节(代表整型成员变量i)的值应该是3和4。而程序结果显示,类HaveVirtual的两个对象h1和h2的头4个字节的内容相同,这个值就是类HaveVirtual的虚函数表所在地址。2.虚函数表(vtable)的内部结
7、构虚函数表是为拥有虚函数的类准备的。虚函数表中存放的是类的各个虚函数的入口地址。那么,可以思考以下几个问题:(1)虚函数的入口地址是按照什么顺序存放在虚函数表中的呢?(2)不同的类(比如说父类和子类)是否可以共享同一张虚函数表的呢?(3)虚函数表是一个类的对象共享,还是一个对象就拥有一个虚函数表?(4)多重继承的情况下,派生类有多少个虚函数表呢?考察如下程序:#includeusingnamespacestd;#defineShowFuncAddress(function)_asm{8mo
8、veax,function}_asm{movp,eax}cout<<"Addressof"#function":"<
(pObj);
此文档下载收益归作者所有