面向對象實驗(七)——多態性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

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