• 虚函数实例解析


    // fa.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include "iostream"
    using namespace std;
    class A{ //虚函数示例代码,实例对象里只有vptr指针
    public:
    virtual void fun(){cout<<1<<endl;}
    virtual void fun2(){cout<<2<<endl;}
    };
    class B:public A{
    public:
    void fun(){cout<<3<<endl;}
    void fun2(){cout<<4<<endl;}
    };


    int main(){
    void (*fun)(A*);//定义了一个函数指针,名字叫做fun,该函数有一个参数,是A*类型的。
    A *p=new B;//向内存自由区申请一个内存单元地址,然后隐式保存在一个指针中,然后把这个地址赋给A类型的指针p。
    long lVptrAddr;//待会儿用来保存vptr的值。
    memcpy(&lVptrAddr,p,4);//他们的实例对象里只有vptr指针,所以我们就放
    //心大胆地把p所指的4bytes内存里的东西复制到lVptrAddr中,所以复制出来的4bytes内容就是vptr的值,即vtbl的地址
    //现在有了vtbl的地址了,那么我们现在就取出vtbl第一个slot里的内容
    memcpy(&fun,reinterpret_cast<long*>(lVptrAddr),4);//取出vtbl第一个slot里的内容,并存放在函数指针fun里。
    //需要注意的是lVptrAddr里面是vtbl的地址,但lVptrAddr不是指针,所以我们要把它先转变成指针类型
    fun(p);//这里就调用了刚才取出的函数地址里的函数,也就是调用了B::fun()这个函数,
    //也许你发现了为什么会有参数p,其实类成员函数调用时,会
    //有个this指针,这个p就是那个this指针,只是在一般的调用中编译器自动帮你处理了而已,而在这里则需要自己处理。
    delete p;//释放空间。
    system("pause");
    }

  • 相关阅读:
    CentOS6.4 安装 codeblocks-12.11
    SpringCloud 进阶之Hystrix(断路器)
    SpringCloud 进阶之Ribbon和Feign(负载均衡)
    SpringCloud 进阶之Eureka(服务注册和发现)
    SpringCloud 入门
    SpringBoot与消息(RabbitMQ)
    SpringBoot 与缓存
    SpringBoot 之数据访问
    Spring Data 之 Repository 接口
    Spring Data之Hello World
  • 原文地址:https://www.cnblogs.com/hackerl/p/3324130.html
Copyright © 2020-2023  润新知