C++中的后期绑定——多态

C++中除了继承之外还一个重要的性质就是多态性,所谓的多态性指的是,只有当程序执行时才决定调用哪个函数,也即“一个接口,多种执行”。这时需要对类中的方法用virtual(虚函数)修饰。所谓的虚函数指的是“一个类中你希望重载的成员函数,当你用一个基类(父类)指针指向一个继承对象的时候,你调用一个虚函数,实际调用的是派生类(继承类)的版本。” ——引自MSDN
例如以下例子中:

#include <iostream>
#include <queue>

using namespace std;

 class Parent{
 public:
    void f(){  //定义父类中的一个方法f
        cout << "Parent::f()" << endl;
    }

    void g(){//定义父类中的一个方法g
        cout << "Parent::g()" << endl;
    }
};

class Child : public Parent{
public:
    void f(){ //重载父类中的方法f
        cout << "Child::f()" << endl;
    }

    void g(){ //重载父类中的方法g
        cout << "Child::g()" << endl;
    }
};

int main()
{
    Child c;
    Parent* p;
    p = &c; //构造一个子类对象,并用基类指针指向它
    c.f();
    c.g(); //通过自身调用f和g方法
    p->f();
    p->g(); //通过基类指针分别调用f和g方法
}

输出结果:
在这里插入图片描述
这时通过基类指针调用的方法并非子类重载后的方法,而是调用了父类中的方法。此时要想调用子类中的方法只能通过定义子类指针或者通过子类对象本身来调用。如果出现一个父类被多个子类继承时,通过定义子类指针的方法来调用子类中的方法就显得比较繁琐,这时便可以用到virtual关键词来修饰父类中的方法,然后让子类重写该方法。例如下面程序需要刻画出多种不同形状的性质:

#include <iostream>
#include <queue>
#include <ctime>
#include <vector>

using namespace std;

 class shape{
public:
    virtual void drawShape(){ //用virtual函数定义刻画图形方法
        cout << "this is a shape" << endl;
    }
 };

 class rectangle : public shape{ //长方形是形状的一个子类
public:
    void drawShape(){
        cout << "this is a rectangle" << endl; //重载父类函数
    }
 };

 class circle : public shape{
 public:
     void drawShape(){
        cout << "this is a circle" << endl;
     }
};

class pentagon : public shape{
public:
    void drawShape(){
        cout << "this is a pentagon" << endl;
    }

};

int main()
{
    srand(time(0)); //定义随机数种子

    vector<shape*> Listshape; //定义一个存储形状地址的容器

    for(int i = 0; i < 10; i++){
        int j = rand() % 3;  //通过随机数任意产生10个形状
        if(j == 2){
            rectangle re;
            Listshape.push_back(&re);
        }
        else if(j == 1){
            circle ci;
            Listshape.push_back(&ci);
        }
        else{
            pentagon pe;
            Listshape.push_back(&pe);
        }
    }

    for(auto *p : Listshape){ //依次刻画这些形状
        p->drawShape();
    }
}

输出结果:
在这里插入图片描述
此时如果去掉父类中的virtual则会出现以下结果:
在这里插入图片描述
当然如果不想使用virtual函数,同时又想得到同样的结果,那么则需要定义3个容器分别存储不同的形状,同时多次使用for循环依次输出。这样的坏处就是造成了大量代码的重复,程序最大的优点莫过于不重复造轮子。因此virtual关键词极大的便利了程序的重复使用。

如有错误,欢迎批评与指正!

猜你喜欢

转载自blog.csdn.net/WJ_SHI/article/details/82467095