zoukankan      html  css  js  c++  java
  • 虚函数实例解析

    // 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");
    }

  • 相关阅读:
    js数组去重五种方法
    wm_concat 多行字符串拼接
    ORACLE WITH AS 简单用法
    layui laytpl 语法
    看懂Oracle执行计划
    GIT RM -R --CACHED 去掉已经托管在GIT上的文件
    sourceTree使用教程--拉取、获取
    SourceTree忽略文件和文件夹
    layui table 详细讲解
    利用POI实现下拉框级联
  • 原文地址:https://www.cnblogs.com/hackerl/p/3324130.html
Copyright © 2011-2022 走看看