关于虚函数(课后整理)

来源:互联网 发布:linux ftp连接日志 编辑:程序博客网 时间:2024/05/16 16:03

记录几个自己认为重要的和还没有完全掌握的知识点。

小小的总结一下:

几个重要的知识点:1、虚函数的实现机制(优点,作用)

                           2、虚析构函数作用

                           3、重写和隐藏的区别

1、虚函数(是动态绑定的技术基础)

    (1)实现机制

           使用virtual关键字,主要用于实现多态,通过使用基类的 指针或引用,执行时根据指针指向的对象的类型,决定调用哪个类的成员函数。

           一般,会使派生类重写基类的virtual函数。举例:

          class B0 //基类B0声明
         {
           public: //外部接口

                virtual void display() //虚成员函数
               {cout<<"B0::display()"<<endl;} 
           };
         class B1: public B0 //公有派生
         {
         public:
               void display()  {  cout<<"B1::display()"<<endl;  }
          };
         class D1: public B1 //公有派生
        {
         public:。
             void display() {  cout<<"D1::display()"<<endl;  }
         };
        void fun(B0 *ptr) //普通函数
        {    ptr->display();    }
         void main() //主函数
       {
              B0 b0,  *p; //声明基类对象和指针
              B1 b1; //声明派生类对象
              D1 d1; //声明派生类对象
              p=&b0;
              fun(p); //调用基类B0函数成员
              p=&b1;
              fun(p); //调用派生类B1函数成员
              p=&d1;
              fun(p); //调用派生类D1函数成员
        }//,没有使用虚函数时,无论传指向谁的指针它都会严格依据实参服从形参的规则,转化为B0类型,输出结果一样为:B0::display()

         引入虚函数,在B0的display()前加virtual即可,输出及结果发生改变,变为我们要得到的结果。

         编译器发现某类含有虚函数,会对其生成的对象加入一个void型的指向指针的指针(为什么void类型,注意!)(二级指针):vptr,并让其指向一个由类维护的虚函数表vtable(其实是个指针数组),每个表项是一个虚函数名(地址),排列次序按虚函数生命的次序。

         在类族中,无论是基类还是派生类都拥有各自的vptr和vtble。相同类型所生成的对象共享了一个vtable。

         (这里其实用图形更清楚表达,以后补上吧)

         派生类新增的虚函数依次排在表的后面。当然,派生类的vtable表项中放的是新的重写了父类同名函数的首址。
         对象中加入的vptr的位置,会因类是class还是struct而不同:或在对象之前端,或在后端。于是造成了父子是class还是struct的不和(不兼容)。
         对象中加入的vptr的位置,还会因编译器的不同而异:有的编译器将vptr加在对象之前端,有的加在后端。VC++是加在前端。
         非虚函数不进入vtable表。

    (2)用于非静态、非友元、内联的成员函数

   (未完待续)

原创粉丝点击