美文网首页C++程序员C语言
c++学习笔记之虚函数

c++学习笔记之虚函数

作者: 旧风景_ | 来源:发表于2017-08-11 16:54 被阅读0次

    普通函数与虚函数的区别

    当类里面没有虚函数只有普通函数时:

    当类里面有虚函数时:

    我们发现this指针的值和类所占的空间大小变了,也就是说当类里面出现虚函数时就会增加4个字节大小的空间。增加的4个字节就在类的首地址处。

    编译器运行时先检查类里面是否有虚函数

    如果有则分配4个字节的大小,然后在检查成员变量并分配空间,最后在执行构造函数。。

    我们来看看增加的那4个字节到底是什么东西

    class Test
    {
    public:
        Test()
        {
            this->i = 2;
            printf("%d\n%d\n", *(int *)this,sizeof(Test));
        }
        virtual void Fun1()
        {
            printf("调用了fun1\n");
        }
        virtual void Fun2()
        {
            printf("调用了fun2\n");
        }
    private:
        int i;
    };
    
    int _tmain()
    {
        Test t;
        Test *p = &t;
        p->Fun1();
        return 0;
    }
    
    //调用构造函数
    003224C8  lea         ecx,[ebp-10h]    
    003224CB  call        00321186  
    
    003224D0  lea         eax,[ebp-10h]  //将存储this指针的地址传给eax
    003224D3  mov         dword ptr [ebp-1Ch],eax  
    003224D6  mov         eax,dword ptr [ebp-1Ch]  
    003224D9  mov         edx,dword ptr [eax]  //将this指针的值传给edx
    003224DB  mov         esi,esp  
    003224DD  mov         ecx,dword ptr [ebp-1Ch]  
    //将this指针的值解引用后传给eax 
    //(也就是将当有类里虚函数时编译器分配的4个字节大小的地址解引用后传给eax)
    003224E0  mov         eax,dword ptr [edx]  
    003224E2  call        eax  //调用this指针存的值
    
    

    分析到这我们知道了 p->Fun1();这个成员函数的地址是this指针存的4字节大小的地址解引用后的值

    我们现在论证一下

    **(int **)p 这这样做是因为this指针是一个地址 而this指针里面又存了一个4字节大小的地址

    运行结果如下:

    我们在看看

    这就证明this指针存的地址指向一个函数地址表 我们称这个函数地址表为虚函数表。


    总结:当一个类出现虚函数时 那么编译器会在类的首地址(this指针)分配一个4字节大小地址 无论虚函数有多少个,编译器都只分配一个4字节的大小的地址,这个地址指向了虚函数表
    虚函数表的大小取决于虚函数的数量。



    若是有错误之处 还请指明!多谢

    相关文章

      网友评论

        本文标题:c++学习笔记之虚函数

        本文链接:https://www.haomeiwen.com/subject/ojolrxtx.html