C++面向对象------多态

1、虚函数、覆盖、多态安全

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

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

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

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

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

 

2、覆盖、重载、隐藏的条件对象

  覆盖(重写):继承

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

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

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

    d、访问修饰符能够不一样

    

  重载:

    a、在同一做用域下

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

    c、返回值能够不一样

  

  隐藏:

    a、在不一样做用域中

    b、函数名相同

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

 

3、多态的条件

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

   二、经过基类指针或引用调用基类的虚函数(该虚函数派生类必需要重写)

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

   四、在子类的构造函数执行前会先调用父类的构造函数,若是调用被覆盖的虚函数,因为子类还没构造完成,所以只能是调用父类中的虚函数构造函数在进入函数体执行时,类中看得见的资源已经所有构造完成

   五、在子类的析构函数执行完成后会再调用父类的析构函数,若是调用被覆盖的虚函数,因为子类已经开始析构完成已经不能算是完整的子类了,所以只能调用父类中的虚函数

 

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

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


  二、抽象类

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

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

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


  三、纯抽象类

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

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

    纯抽象类是类封装的过程,同时抽象类也能够当作一个统一的接口

6、虚函数表

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

    二、如何证实这张表存在

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

    三、一个类只有一张虚函数表,全部对象共享一张虚函数表

    四、通常对象的前4字节是指向虚函数表的指针


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

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

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

  四、使用多态会产生额外的一些代码和调用,所以使用多态会下降代码的执行速度



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

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

  三、在设计类时若是析构函数什么都须要作,编译器也会生成一个空的析构函数,但这样会让继承它的子类会有安全隐患

  四、最好把全部的析构函数都设置为虚函数

相关文章
相关标签/搜索