C++之多态的初识

1.多态

   C++是一门面向对象的编程语言,体现在: 封装,继承,多态
   多态: 指同一种类型的指针/引用  ,调用相同的函数 表现出来不同的形态

  1.1多态的特性

    (1)通过指向子类对象的基类指针/引用  只能调用基类的成员函数
    (2)通过指向子类对象的基类指针/引用  调用虚函数,那么实际上调用的是子类中的版本
    (3)虚函数和虚函数覆盖
       虚函数: 使用virtual 关键字修饰的成员函数
       虚函数覆盖: 在子类中定义一个与基类中具有相同函数原型的成员函数,即构成虚函数覆盖,
                  该虚函数的覆盖版本也是虚函数(虽然没有使用virtual修饰)

  1.2 虚析构

    (1)虚析构函数实际上就是为了保证delete一个指向子对象的基类指针时,实际被调用的就是子类中的析构函数,
       该析构函数会自动调用基类中的析构函数

    (2)一般而言,如果一个类中存在虚函数,那么该类就应该提供一个虚析构函数

 1.3.多态的底层实现

   如: 虚函数表可以看成是一个函数指针数组;

    int arr[5]; arr的类型是int*

    int* arr[5]; arr的类型是int**
    void (*pFun)(void) ---->函数指针,指针名为pFun
    pFun p[2] = ()&a; ---->pp的类型是pFun*
    pFun* pp[2] =     ---->pp的类型是pFun**
    typedef void (*pFun)(void);//定义函数指针,其别名为pFun
                        typedef pFun* ppFun;//虚函数中元素地址的数据类型
                        A a;ppFun pp = *(ppFun*)&a;//&a是A*类型的,所以做类型转换
     class A
     {public:
          virtual void foo(void){.....}
     };
     class B : public A
     {
         void foo(void){......}
     };
     A* pa = new B;
     pa->foo();
   当编译器编译上述代码时,不知道pa所指向对象的真实身份,只有在运行时才会知道,
   于是编译器所能做的就是用一段代码去替换上面的函数调用语句,这段代码依次指向下面的操作:
   (1)首先弄清指针pa所指向对象的真实身份
   (2)然后通过这个对象的虚函数表指针去访问其虚函数表,在虚函数表中找到与foo函数标识符对应的虚函数入口地址
   (3)根据虚函数入口地址,调用该函数 

  1.4多态的必要条件:

    (1)首先要有虚函数
    (2)通过指针或引用 调用虚函数

  1.5扩展笔试题:

 笔试题:
      class A
      {
      public:
            void foo(void)
            {bar();//this = &b; this->bar();//产生了多态,调用了B类中的bar函数
            }
            virtual void bar(void){}
      };
      class B : public A
      {
      public:
            void bar(void){}
      };
      int main(void)
      {
         B b;
         b.foo();//请问foo 函数中调用的哪个bar函数???
      }  
   (2)构造函数、析构函数、运算符函数、静态成员函数,哪些不可以是虚函数?为什么?
      构造函数不可以是虚函数,因为虚函数表是依赖对象的,构造函数是创建对象之前工作的
      静态成员函数不可以是虚函数,因为它属于整个类

1.6 纯虚函数、抽象类、纯抽象类

   (1)纯虚函数
       形如: virtual 返回值类型  函数名(形参表) = 0;
   (2)抽象类
       至少包含一个纯虚函数的类,抽象类不能实例化对象
   (3)纯抽象类
       完全由纯虚函数组成的抽象类
   注意:
       纯虚函数在基类中是没有定义的,要求在子类中加以实现,如果一个抽象类的子类没有对基类中的全部虚函数提供覆盖版本,那么该子类也是抽象类;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值