zoukankan      html  css  js  c++  java
  • C++面向对象------多态

    一、虚函数、覆盖、多态

      虚函数:在定义时添加virtual关键字的成员函数,叫虚函数

      覆盖:在子类中实现与父类中虚函数相同的函数,那么子类中的成员函数会覆盖父类中的成员函数

        不同于隐藏,隐藏是在父子类之间名字相同的标识符,只要不够成覆盖,就是隐藏。子类会隐藏父类中的同名函数

      多态:如果子类中的成员函数对父类中的成员函数进行了覆盖,那么当一个指向子类的父类指针或引用了子类的父类引用,在调用此同名函数时会调用子类中的函数,而不是父类中的虚函数,这种语法现象叫多态。

      多态的意义在于同一种类发出同一种调用而产生不同的反映

    二、覆盖、重载、隐藏的条件

      覆盖(重写):

        a、不在同一作用域,分别在基类和派生类

        b、函数名、参数、返回值相同

        c、基类函数必须有virtual关键字

        d、访问修饰符可以不同

        

      重载:

        a、在同一作用域下

        b、函数名相同,参数不同

        c、返回值可以不同

      

      隐藏:

        a、在不同作用域中

        b、函数名相同

        c、在基类和派生类中只要不构成覆盖就是隐藏

    三、多态的条件

       1、派生类必须重写基类的虚函数。

       2、通过基类指针或引用调用基类的虚函数(该虚函数派生类必须要重写)

       3、当指针或引用已经构成多态时,此时调用成员所传的this指针再调用成员函数时也构成多态

       4、在子类的构造函数执行前会先调用父类的构造函数,如果调用被覆盖的虚函数,由于子类还没构造完成,因此只能是调用父类中的虚函数构造函数在进入函数体执行时,类中看得见的资源已经全部构造完成

       5、在子类的析构函数执行完成后会再调用父类的析构函数,如果调用被覆盖的虚函数,由于子类已经开始析构完成已经不能算是完整的子类了,因此只能调用父类中的虚函数

    四、纯虚函数和抽象类
      1、纯虚函数
        class A
        {
          public:
          virtual void test(void) = 0;
          virtual void test(void) const = 0;
        };
        a、纯虚函数不需要被实现,如果非要实现也不能在类中,必须要在类外(虚函数)

        b、纯虚函数如果想调用必须在子类中覆盖,然后以多态的方式调用


      2、抽象类

        成员函数中有纯虚函数的叫抽象类,这种类不能创建对象。

        如果子类继承了抽象类,则必须把父类中的纯虚函数覆盖了,否则他也变成了抽象类不能被实例化

        因此抽象类只能以指针或引用的方式指向子类来调用非纯虚函数


      3、纯抽象类

        所有的成员函数都是纯虚函数,这种类叫纯抽象类

        面向对象的四大特性:抽象、封装、继承、多态

        纯抽象类是类封装的过程,同时抽象类也可以当做一个统一的接口

    六、虚函数表

        1、什么是虚函数表,当一个类中有虚函数时,编译器会为这个函数分配一个专门记录这些的虚函数表,在类中会有一个隐藏的指针成员指向这张表

        2、如何证明这张表存在

          有虚函数的类会比没有虚函数的类(相同的)多4字节,还会添加补齐和对其

        3、一个类只有一张虚函数表,所有对象共享一张虚函数表

        4、一般对象的前4字节是指向虚函数表的指针


    七、动态类型绑定(多态)
      1、当使用父类指针或引用指向子类时,编译器并没有立即生成调用函数的指针,而是生成了一段代码,用于检查指针指向的真正的对象是什么类型

      2、在代码真正运行时才通过对象的指针找到指向虚函数的成员指针

      3、再通过成员指针访问到虚函数表,再从中找到调用的函数地址

      4、使用多态会产生额外的一些代码和调用,因此使用多态会降低代码的执行速度



    九、虚析构
      1、如果通过父类指针或引用指向子类对象,当使用delete释放对象时,此时只能调用父类的析构函数,如果子类中使用new/malloc申请了内存资源,那么将导致内存泄漏

      2、解决方法就是把父类的析构函数设置为虚函数

      3、在设计类时如果析构函数什么都需要做,编译器也会生成一个空的析构函数,但这样会让继承它的子类会有安全隐患

      4、最好把所有的析构函数都设置为虚函数

     

  • 相关阅读:
    开发中的一些总结。。。
    Directory Listing Denied错误
    webservice的一些使用心得。。
    vs2005 sp1 补丁后,不能初始化
    谈C/C++指针精髓
    CString 的函数
    javaScript 中 call 函数的用法说明 & 继承
    条款12: 尽量使用初始化而不要在构造函数里赋值(effectiveC++)
    js日期时间函数(经典+完善+实用)
    学习之路一 记录学习中的手记
  • 原文地址:https://www.cnblogs.com/xkk956227639/p/9470687.html
Copyright © 2011-2022 走看看