天天看点

多态性,虚函数与纯虚函数(复习干货)多态性,虚函数与纯虚函数(复习干货)

多态性,虚函数与纯虚函数(复习干货)

向对象发送同一个消息,不同的对象在接收时会产生不同的
   行为(即方法,属于本对象的行为)。
           
  1. 多态分为静态多态性和动态多态性。
  • 静态多态性,函数重载和运算符重载都属于静态多态性。
  • 动态多态性,通过虚函数实现。
  1. 静态多态性:编译阶段确定函数地址(地址早绑定)。

          函数调用速度快,效率高,但是缺乏灵活性。

     动态多态性:运行阶段确定函数地址(地址晚绑定)。

利用虚函数实现动态多态性

  1. 所谓虚函数,就是在基类中声明函数是虚拟的,并不是实际存在的函数,然后在派生类中才正式定义此函数。
  2. 虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应。
  3. 虚函数
  • 基类中声明(virtual),在类外定义虚函数不必在函数名前加virtual,函数体可以是空,它的作用只是定义了一个虚函数名,具体功能留给派生类去添加实现。
  • 在派生类中声明时,virtual可以写,也可以不写,但习惯性一般在每一层声明该函数时都加virtual,使程序更加清晰。
  • 在派生类中重新定义此虚函数,函数类型,函数名,函数参数个数及参数类型必须与基类的虚函数相同。
  1. 虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。   

    Base类.h文件

#include<iostream>
    usaing namespace std;
    class Base
    {
        public:
            Base(int a,  int b){ this->a = a;  this->b = b;}
            virtual  void  display();
        private:
            int a;
            int b;
     };
           

基类.cpp文件

#include"Base.h"

void Base::dispaly()
{
   cout<<"我是基类"<<endl;
   cout<<"a="<<a<<"\t"<<"b="<<b<<endl;
   // 可以是空
}
           

派生类.h文件

#include"Base.h"
class  Son :
   public  Base
{
    public: 
        Son(int a, int b, int c):Base(a,b){this->c = c;}
        virtual void display();
    private:
        int c;
};
           

派生类 .cpp文件

#include"Son.h"

void Son::display()
{
   cout<<"我是Son的虚函数"<<endl;
   cout<<"a = "<<a<<"\tb="<<b<<"\tc="<<c<<endl;
}
           

main函数

#include"Son.h"
int main()
{
   Son s(1,2,3);
   Base *p = s; 
   p->display();
   return 0;
}
           

运行结果:

我是Son的虚函数
  a=1	b=2   c=3
           

纯虚函数

  1. 什么是抽象类?

    凡是包含纯虚函数的类都是抽象类。由于它常作为基类,通常称为抽象基类。因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的(可以建立基类的指针或引用),抽象类的作用是作为一个类族的共同基类,或者说,为一个类族提供一个公共接口。(顶部可以有好几层都是抽象类)

  • 静态成员函数不能定义为虚函数,也不能定义成纯虚函数。
  1. 定义这些抽象类的唯一目的是用它作为基类去建立派生类。
  2. 什么是具体类?

    在抽象类所派生的新类中对基类的所有纯虚函数进行定义,那么这些函数就被赋予了功能,可以被调用,这个派生类就不是抽象类,而是可以定义对象的具体类。

  • 如果在派生类中没有对所有纯虚函数进行定义,则此派生类仍然是抽象类,不能定义对象。
  • 当派生类成为具体类后,就可以用基类指针指向派生类对象,用指针调用虚函数,实现多态。
  1. 派生类对基类的纯虚函数进行定义后,该函数就成为了虚函数,而不是纯虚函数。
  2. 纯虚函数声明: virtual 函数类型 函数名 (参数列表) = 0;

    只需要声明,不需要在基类具体实现。

    声明如下:

virtual   void   display() =  0;
           
  • 派生类中必须与基类拥有相同的函数类型,函数名,参数个数以及参数类型。

基类 .h文件

#include<iostream>
using namespace std;

class Shape
{
public:
	virtual double area() = 0;
	virtual void display() = 0;
};
           

派生类 .h文件

#include "Shape.h"
class Triangle :
    public Shape
{
    //三角形
public:
    Triangle(int side, int high) { this->side = side; this->high = high; }
    virtual double area();
    virtual void display();
private:
    int side;
    int high;
};
           

派生类 .cpp文件

#include "Triangle.h"

double Triangle::area()
{
	return (double)side * high * (1.0/2);
}

void Triangle::display()
{
	all_area += area();
	cout << "Triangle的面积是:" << area() << endl;
}
           

main函数

#include"Triangle.h"

int main()
{   Triangle e(2, 4);
    Shape* pt;
    pt = &e;
    pt->display();
           

运行结果:

Triangle的面积是:4
           

继续阅读