关于C++中类的虚函数

   看了好多的博客,其中很多对我帮助很大.这么我也写一回博客,讲讲的的心得。C++的书看了很多,C++反汇编很值得学习,不是为了真的去做反汇编,而是去更深入理解C++那些复杂语法背后发生的事情。关于C++虚函数,在定义了虚函数的类中,需要构造函数来初始化虚函数指针。将虚表地址赋值于类的头部。具体看代码;

#include <iostream>

using namespace std;

struct A
{
    A(int a)
    {
        x = a;
        prin();
    }
    virtual void prin()
    {
        cout << "x";
    }
    virtual ~A()
    {
    }
    int x;
};

int main()
{
    A a(1);
    return 0;
}

在A的对象被创建时,B的构造函数中发生了很多事,下面一一道来。

7  	    A(int a)
0x00420140	push   %ebp
0x00420141	mov    %esp,%ebp
0x00420143	sub    $0x18,%esp
0x00420146	mov    %ecx,-0xc(%ebp)
8  	    {
0x00420149	mov    -0xc(%ebp),%eax
0x0042014C	movl   $0x4735b8,(%eax)
9  	        x = a;
0x00420152	mov    -0xc(%ebp),%eax
0x00420155	mov    0x8(%ebp),%edx
0x00420158	mov    %edx,0x4(%eax)
10 	        prin();
0x0042015B	mov    -0xc(%ebp),%eax
0x0042015E	mov    %eax,%ecx
0x00420160	call   0x420120 <A::prin()>
11 	    }
0x00420165	leave
0x00420166	ret    $0x4
7  	    A(int a)
0x00420140	push   %ebp
0x00420141	mov    %esp,%ebp
0x00420143	sub    $0x18,%esp
0x00420146	mov    %ecx,-0xc(%ebp)
8  	    {
0x00420149	mov    -0xc(%ebp),%eax
0x0042014C	movl   $0x4735b8,(%eax)
9  	        x = a;
0x00420152	mov    -0xc(%ebp),%eax
0x00420155	mov    0x8(%ebp),%edx
0x00420158	mov    %edx,0x4(%eax)
10 	        prin();
0x0042015B	mov    -0xc(%ebp),%eax
0x0042015E	mov    %eax,%ecx
0x00420160	call   0x420120 <A::prin()>
11 	    }
0x00420165	leave
0x00420166	ret    $0x4

以上为A构造函数中汇编代码,加粗加红的部分即为初始化虚表操作。所谓的类,就是一个struct,类中函数与类的关联在于编译器为每个类中函数加了一个参数,为struct对象的首地址,仅此而已。

mov    %ecx,-0xc(%ebp)

其中的ecx寄存器中的值即为类对象a的首地址。由于有虚函数,需要类对象第一个void *指针类型大小的空间存放虚表指针,所以将ecx值保存,在取出值赋值给eax,$0x4735b8即为虚表首地址。来看看它所在内存空间的值

0x4735b8: 20 01 42 00 8c 01 42 00|6c 01 42 00 00 00 00 00 

小端模式,32位编址位数。值为0x420120,该值即为虚函数print的地址。下面加粗加蓝的语句及调用该地址。有虚函数的类需要有构造函数,没有编译器会提供来初始化虚表指针。虚表指针空间之后即为类成员空间。开始处ecx的值加4就是int a的地址了。

今天就写到这里了。以后再写继承下虚函数机制的各种隐藏操作。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值