面向对象实验(七)——多态性2

理论

基类类型对象入口索引子类对象
1.泛化的概念:由具体的,个别的扩大为一般的;将此概念应用于结构体和类对象,就是泛化能力。类型泛化指的是在继承和派生时,基类派生出了很多不同的子类,形成了继承树,生成的子类都有自己独特的性质,但是所有的子类都有自己的独特性质,但是所有的子类都具有基类的性质,所以也可以看作是基类对象。
2.不同的子类对象都可以用基类指针索引到,但是如果用统一的方式索引到之后,遇到相同的函数入口,只会执行子类函数中的函数。也就是说,调用基类指针后,虽然指向的是派生类对象,但是调用的仍旧是基类的函数。如果想要调用派生类的话,应当将所有的同名函数设置为虚函数。
基类指针指向子类对象如何展现子类性质:虚函数
1.虚函数的概念:虚函数:在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数。可以实现多态性。
2.动态绑定:虚函数和虚析构函数
含有虚函数的类要使用虚析构函数,否则容易导致派生类的资源无法释放。
派生类的构造函数是先构造的基类的无名对象,析构的时候按照基类的类型析构。
所以也会调用小模块的析构函数。
当基类指针指向派生类对象时,加上virtual就可以调用派生类的析构函数去析构派生类对象。
3.抽象类和纯虚函数
会发现有的类不需要产生对象,只是作为最顶层往下继承,每一个派生类的对象都是调用各自虚函数的函数体,因为基类里虚函数的函数体可以忽略,变成了纯虚函数,同时因为函数体不存在,也不能产生对象,变成了抽象类。
4.派生类构造函数执行的次序:
调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左到右);
调用内嵌成员对象的构造函数,调用顺序按照它们在类中声明的顺序;
派生类的构造函数体中的内容。
代码:

#include<bits/stdc++.h>
#define PI 3.1415926
using namespace std;
class Shape
{
	protected:
		int width,height;
	public:
		Shape(){}
		Shape(int a,int b):width(a),height(b){}
		void set_values(int a,int b){
		    width=a;height=b;}
		virtual int area()=0;///纯虚函数
		~Shape(){}
};
class circle:public Shape///圆
{
	public:
		circle(){}
		circle(int a,int b):Shape(a,b){}
		virtual int area(){
		    return width*width*PI;}
};
class Rectangle:public Shape///矩形
{
	public:
		Rectangle(){}
		Rectangle(int a,int b):Shape(a,b){}
		virtual int area(){
		    return width*height;}
		~Rectangle(){}
};
class Triangle:public Shape///三角形
{
	public:
		Triangle(int a,int b):Shape(a,b){}
		virtual int area(){
		    return width*height/2;}
		~Triangle(){}
};

void Print_area(Shape& t1,Shape& t2,Shape& t3){
    Shape* p1=&t1;
    cout<<p1->area()<<endl;
    p1=&t2;
    cout<<p1->area()<<endl;
    p1=&t3;
    cout<<p1->area()<<endl;
}

int main(){

	Shape* p1;
	Rectangle rec_1(10,15);
	Triangle tri_1(10,6);
	circle cir_1(1,1);
    Print_area(rec_1,tri_1,cir_1);
    return 0;
}

输出结果:
150
30
3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章