C++多态之虚函数本质

struct Animal{
    int weight;
    void run(){
        cout << "animal run"<run();
    
    Animal *p2 = new Animal();
    p2->run();
    Animal animal;
    cout<

打印结果
animal run
animal run
4
我们传入了指向dog对象的指针,预期的是调用子类dog里的run函数,可实际还是调用父类,要实现这点需要在父类函数添加virtual关键字

struct Animal{
    int weight;
    virtual void run(){
        cout << "animal run"<

再运行,结果输出:
Dog run
animal run
16 // 架构不同这个数可能有差异
查看汇编代码,没加virtual时

    0x100003192 <+66>:  callq  0x1000031d0               ; Animal::run at main.cpp:12
    0x1000031c3 <+115>: callq  0x1000031d0               ; Animal::run at main.cpp:12

可以看出两个指针都是调用同一地址,这个是父类函数地址;
加virtual时

    0x100003091 <+81>:  callq  *(%rcx)
    0x1000030ce <+142>: callq  *(%rdx)

这时他们分别调用的两个寄存器上不同地址,很明显这就是virtual起的作用;
当不使用virtual时,对象地址默认是第一个成员变量地址,使用virtual后,其地址内存存储了其虚表的地址值,虚表里放着Animal里标记的虚函数的调用地址。
在C++里对象找方法都是直接去相应虚表里面找,这与OC子类父类层级找不同的。

你可能感兴趣的:(C++多态之虚函数本质)