(一)

先编写函数:

#include <iostream> 
using namespace std;

class Shape
{
protected:
int width, height;

public:
Shape( int a = 0, int b = 0)
{
width = a;
height = b;
}

int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};

class Rectangle: public Shape
{
public:
Rectangle( int a = 0, int b = 0)
{
}

int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};

class Triangle: public Shape
{
public:
Triangle( int a=0, int b=0) : Shape(a, b) { }

int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};


int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);

// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();

// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();

return 0;
}

运行结果:

Parent class area
Parent class area

程序分析:
(1)Shape( int a = 0, int b = 0)
这里直接给函数的形参赋了默认的初值,作用是:在函数调用时,省略部分或全部参数,这时就会使用默认参数进行代替
(2)Rectangle( int a = 0, int b = 0) : Shape(a, b) { }
这段代码的意思是,在构造函数Rectangle中,先调用父类的构造函数Shape。
(3)shape指针调用函数 area() 时,被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接–函数调用在程序执行前就准备好了。
有时候这也被称为早绑定,因为 area() 函数在程序编译期间就已经设置好了。

(二)

对程序稍作修改,在 Shape 类中,area() 的声明前放置关键字 virtual,如下所示

class Shape
{
protected:
int width, height;

public:
Shape( int a = 0, int b = 0)
{
width = a;
height = b;
}

virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};

运行结果:

Rectangle class area
Triangle class area

程序分析:
(1)虚函数
虚函数是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。
(2)此时,编译器看的是指针的内容,而不是它的类型。因此,由于 tri 和 rec 类的对象的地址存储在 *shape 中,所以会调用各自的 area() 函数。
正如您所看到的,每个子类都有一个函数 area() 的独立实现。这就是多态的一般使用方式。有了多态,您可以有多个不同的类,都带有同一个名称但具有不同实现的函数。


更多内容请关注微信公众号

小朋友学C++(12):多态_虚函数