美文网首页
C++多态之虚函数本质

C++多态之虚函数本质

作者: wangwhatlh | 来源:发表于2021-11-13 13:02 被阅读0次
    struct Animal{
        int weight;
        void run(){
            cout << "animal run"<<endl;
        }
    };
    
    struct Dog:Animal{
        int age;
         void run(){
            cout<<"Dog run"<<endl;
        }
    };
    
    int main(int argc, const char * argv[]) {
        // insert code here...
        Animal *p1 = new Dog();
        p1->run();
        
        Animal *p2 = new Animal();
        p2->run();
        Animal animal;
        cout<<sizeof(animal)<<endl;
        return 0;
    }
    

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

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

    再运行,结果输出:
    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++多态之虚函数本质

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