虚函数的实现机制图示

     c++规定了虚函数的行为,但将实现留给了编译器作者,不需要知道实现方法就可以使用虚函数,但了解虚函数的工作原理有助于更好的理解概念。
    通常编译器处理虚函数的方法是:给每个对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针。这种数组称为虚函数表。
    虚函数表中存储了为类对象进行声明的虚函数的地址。例如:基类对象包含一个指针,该指针指向基类中所有虚函数的地址表。派生类对象将包含一个指向独立地址表的指针。如果派生类提供了虚函数的新定义,该虚函数表将保存新函数的地址;如果派生类没有重新定义虚函数,该vtbl将保存函数原始版本的地址。如果派生类定义的新的虚函数,则该函数的地址也将被添加到vbtl中。注意,无论类中包含的虚函数是1个还是10个,都只需在对象中添加1个地址成员,只是表的大小不同而已。举例如下:

    class Scientist {
            ...
            char name[40];
    public:
            virtual void show_name();
            virtual void show_all();
             ...
    }

    class Phisicist :public Scientist {
            ......
            char field[40];
    public:
            void show_all();//refined
            virtual void show_field();//new
            ......     
    }


调用虚函数时,程序将查看存储在对象中的vtbl地址,然后转向相应的函数地址表。如果使用类声明中的定义的第一个虚函数,则程序将使用数组中的第一个函数地址,并执行具有该地址的函数。如果使用类声明中的第三个虚函数,程序将使用地址为数组中第三个元素的函数 。


静态联编和动态联编:
     程序调用函数时,将使用哪个可执行代码块哪?编译器负责回答这个问题。将源代码中的函数调用解释为执行特定的函数代码块被称为函数名联编。在c语言中,这非常简单,因为每个函数名都对应一个不同的函数。在c++中由于函数重载的缘故,这项任务更复杂。编译器必须查看函数参数以及函数名才能确定使用哪个函数。然而,c/c++编译器可以在编译过程中完成这种联编,在编译过程中的进行联编称为静态联编。不过虚函数使这项工作变得更困难!正如上述程序,使用哪一个函数是不能在编译是确定的,因为编译器不知道用户将选择那种类型的对象。所以,编译器必须生成能够在程序运行时选择正确的虚方法的代码,这被称为动态联编。 (c++ primmer plus)
c++多态:a:编译时多态 :通过重载函数实现
                b:运行是多态:通过虚函数实现

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helloworddm

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值