虚函数 和 纯虚函数

简单的说,“接口”就是该类的public函数。由于在类的外部一般只能通过这些公共函数才能访问一个类,所以这些函数就称为类的接口。虽然一个类也可以存在public成员数据,但是,一般不要编写这种能够直接在类的外部访问的public数据,因为这样就使信息隐藏性受到一定的“破坏”。
           当使用一个基类的指针指向其一个派生类的实体时,利用该指针调用一个函数,如果这个函数在基类的定义中使用了virtual关键字,那么,这个函数在派生类中自动也是虚函数(前提:此函数没有被“重载”[注:重载的实质是函数名未发生改变,但是函数的参数个数、参数类型、或者类型的顺序发生改变,重载也叫做“静态多态性”],但是可以重新定义其可执行语句)。这个时候,就会发生函数的动态绑定--也就是执行的函数不再是指针所属类的成员函数,而是针所指向的对象对应类的同名函数。
例如,以下的代码片段:
class   Base
{
       
       public:
             virtual   get(){...}//基类里面的虚函数
           ......
};
class   Derived   :public   Base
{
       public:
             get(){...}//该函数在派生类自动为虚拟函数
           ......
};
int   main()
{
          Base   *pB;
          pB=new   Derived;
          pB-> get();//运行时动态绑定,执行Derived::get()函数
        ......
}
             那么,这是不是说,如果有以下的语句:
        Base   *pB;
          pB=new   Base;
          pB-> get();
函数就不再是动态绑定呢?答案是:还是动态绑定。只要用 "pointer-> Virtual_Function(); ",就会发生函数调用的动态绑定。
           这是为什么呢?
           这是因为,编译器再编译上述代码的时候,做了三项工作:
     1、为每一个含有虚函数的类制造一个唯一的虚函数表(VTable),虚函数表是一个虚函数入口地址数组,每一个成员就是一个虚函数的指针(入口地址);
     2、每实例化一个含有虚函数的对象,就为该对象增加一个VPtr(虚函数表指针)做为该对象的首成员数据,它保存的值固定的,即其所属类的VTable地址;
     3、编译 "pointer-> Virtual_Function(); "时,不是直接确定被调函数的地址(直接确定被调函数地址就是“静态绑定”了),而是插入以下的代码:
           3.1   访问pointer所指向的真实对象的Vptr,从而得到该对象所属类的唯一VTable地址;
           3.2   访问VTable,查阅被调函数的地址;
           3.3   按照3.2的结果,执行相应的函数代码.
       
             纯虚函数是在基类里面,没有给出实现,而是直接赋值为0的虚函数.例如:
class   Instrument
{
          public:
                   virtual   void   play()=0;//这就是纯虚函数
                 ......
}
             纯虚函数没有任何动作,也没有入口地址,因而不会填写Vtable里面的指针的值,仅仅用作占据虚函数表位置(因为无论你在派生类里用什么样的顺序实现多个虚拟函数,在派生类的虚函数表中,从基类继承来的虚函数在派生类的Vtable中的顺序,仍然保持与基类的相同).
             此外,纯虚函数还有两个作用:
             一是,纯虚函数表示其所属类是一个抽象类(至少包含一个纯虚函数的类叫作抽象类),抽象类不能被实例化;
             二是,纯虚函数表示其自身仅仅是一个基类接口,其所属类的某个派生类必须实现这个接口函数.否则,派生类还是包含纯虚函数,还是抽象类,不能被实例化;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值