美文网首页
理解虚函数和虚表内存结构

理解虚函数和虚表内存结构

作者: fertilizer | 来源:发表于2017-07-21 10:45 被阅读0次

2017.7.21

虚函数是C++多态性的主要组成部分。下面我简单地从单继承分析虚表具体的内存结构。
先列举一个实例。

#include <iostream>
class base {
public:
    base() {}
    base(int i) {
        this->i = i;
    }
    void print() {
        std::cout << "base print" << std::endl;
    }
    virtual void print_v() {
        std::cout << "base print_v" << std::endl;
    }

private:
    int i;
};

class derived: public base{
public:
    derived() {}
    derived(int i, int j): base(i) {
        this->j = j;
    }
    void print() {
        std::cout << "derived print" << std::endl;
    }
    virtual void print_v() {
        std::cout << "derived print_v" << std::endl;
    }
private:
    int j;
};

int main( int argc, char *argv[]) {
    base* instance1 = new derived(1, 2);
    instance1->print();
    instance1->print_v();
    return 0;
}

图1为上述代码的结果图

图1
可以发现base类的指针指向派生类对象,调用非虚函数print()时,实际调用了base::print();调用虚函数print_v(),实际调用了derived::print_v(),那么原因是什么呢?首先我们需要了解一下虚表的结构。
![图2 base和derived情况](https://img.haomeiwen.com/i1215789/3eddc63b753cc1d6.png?
![Uploading IMG_1429_169073.JPG . . .]
imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
图2 右侧代表虚指针的地址

虚表属于每一个类,类实例化后对象的首地址存有虚指针,该指针指向虚表的首地址。在上述代码中添加一行代码

typedef (void)(*fun)(void);
fun f1 = (fun)*(*((uint64_t **)instance1));
f1()

输出为

derived print_v


这里需要注意,转化类型应该符合该操作系统的内存结构。这里环境是macos sierra

图3 覆盖的内容

然而非虚成员函数没有被覆盖,因为成员函数并没有保存在对象中,编译期确定,并静态或动态绑定到对应的对象上。

所以base类型的指针调用的是继承类的虚函数

对象实例的虚指针指向对应的虚表,虚表中的虚函数是定义类时就形成的。
ps: 虚表结构
包括vptr,RTTI, top offset,接下来我将对多重继承和虚表结构深入理解。

相关文章

  • 理解虚函数和虚表内存结构

    2017.7.21 虚函数是C++多态性的主要组成部分。下面我简单地从单继承分析虚表具体的内存结构。先列举一个实例...

  • 第二周(Geek Band)

    对象模型 1、vptr和vtbl(虚函数与虚表) 调用虚函数vfun,通过虚指针vptr找到虚表vtbl,通过虚表...

  • GEEKBAND面向C++下第二周

    虚指针和虚表 vptr vtbl vptr:虚指针,内存占用4字节,只要类里面有虚函数,就会产生指针,如左图,一万...

  • Part2_Week2(boolan)

    vptr和vtbl:如果类中包含虚函数,则其对象中包含一个虚指针,虚指针指向一个虚表,虚表指向虚函数的定义。虚函数...

  • 第五周Boolan

    对象模型 vptr(虚表指针) 和vtbl(虚函数表) 继承函数指的是继承调用权 而不是内存的大小 静态绑定与动态...

  • c++虚函数与虚表初步

    虚指针与虚表 虚表和虚函数是为了实现动态多态的机制,由编译器实现 当一个类本身定义了虚函数,或其父类有虚函数时,编...

  • 虚表、虚函数

    什么是虚函数? 使用 virtual 关键字修饰的函数即为虚函数,virtual 关键字只能对类中的非静态函数使用...

  • C++虚函数小结

    小例子 参考 虚函数用法 虚函数 理解虚函数

  • C++——虚函数表,常见问题,RTTI,typecast

    一、虚表 函数指针数组虚表的位置 override就是子类写的虚函数将父类的虚函数覆盖 虚表是在对象生成的时候才有...

  • 智能指针

    智能指针可以不手动释放内存? 虚函数中虚构函数定义为虚函数的话,自动调用子类父类的虚函数释放内存。

网友评论

      本文标题:理解虚函数和虚表内存结构

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