纯虚函数与基类指针数组的应用

使用虚函数是实现动态联编的基础。正确使用虚函数,需要满足下列条件:
(1)具有符合类型兼容规则的公有派生类层次结构。
(2)在派生类中重新定义基类的虚函数,对其进行覆盖。
(3)通过基类指针或基类引用访问虚函数。

1、题目内容:
定义抽象基类Shape, 其中纯虚函数printName()输出几何图形的名称和相应的成员数据、纯虚函数printArea()计算几何图形的面积。并由Shape类派生出5个派生类:Circle(圆形),数据成员为半径、Square(正方形) ,数据成员为边长、Rectangle(长方形) ,数据成员为长和宽、Trapezoid(梯形) ,数据成员为上底、下底和高、Triangle(三角形) ,数据成员为底和高。测试过程,定义一个指向基类的指针数组,使其每个元素指向一个动态产生的派生类对象,分别调用相应的成员函数显示各个几何图形的属性及面积,最终输出总面积值。

输入格式:
依次输入圆半径、正方形边长、长方形长宽、梯形上底下底和高、三角形底边和高,均为实数。

输出格式:
请参考输出样例,建议直接复制样例中的部分文字粘贴进自己的代码。圆周率取 3.14159
注意输出中的标点符号、空格。
输入样例:
10
5
2 4
1 2 3
4 3

输出样例:
圆:半径=10,面积:314.159
正方形:边长=5,面积:25
长方形:长=2,宽=4,面积:8
梯形:上底=1,下底=2,高=3,面积:4.5
三角形:底边=4,高=3,面积:6
总面积:357.659

#include<iostream>
using namespace std;
class shape
{
public:
	virtual void printname()=0;//纯虚函数
    virtual double printarea()=0;//纯虚函数
};
class circle:public shape
{
private:
	double r;
public:
	circle(double R){r=R;}
    void printname()
	{cout<<"圆:半径="<<r;}
	double printarea()
	{cout<<",面积:"<<r*r*3.14159<<endl;return r*r*3.14159;}
};
class square:public shape
{
private:
	double a;
public:
	square(double A){a=A;}
	void printname()
	{cout<<"正方形:边长="<<a;}
	double printarea()
	{cout<<",面积:"<<a*a<<endl;return a*a;}
};
class rectangle:public shape
{
private:
	double a,b;
public:
	rectangle(double A,double B){a=A;b=B;}
	void printname()
	{cout<<"长方形:长="<<a<<",宽="<<b;}
	double printarea()
	{cout<<",面积:"<<a*b<<endl;return a*b;}
};
class trapezoid:public shape
{
private:
	double d1,d2,h;
public:
	trapezoid(double D1,double D2,double H){d1=D1;d2=D2;h=H;}
	void printname()
	{cout<<"梯形:上底="<<d1<<",下底="<<d2<<",高="<<h;}
	double printarea()
	{cout<<",面积:"<<(d1+d2)*h/2.0<<endl;return (d1+d2)*h/2.0; }
};
class triangle:public shape
{
private:
	double d,h;
public:
	triangle(double D ,double H){d=D;h=H;}
	void printname()
	{cout<<"三角形:底边="<<d<<",高="<<h;}
	double printarea()
	{cout<<",面积:"<<d*h/2.0<<endl;return d*h/2.0;}
};
int main()
{
	int i;
	shape *p[5];//定义一个指向基类的指针数组,使其每个元素指向一个动态产生的派生类对象,也可以用基类引用
	double r,t=0;
     cin>>r;
	p[0]=new circle(r);//动态分配对象
	double a;
	cin>>a;
	p[1]=new square(a);//动态分配对象
	double b;
	cin>>a>>b;
	p[2]=new rectangle(a,b);//动态分配对象
	double h;
	cin>>a>>b>>h;
	p[3]=new trapezoid(a,b,h);//动态分配对象
	cin>>a>>b;
	p[4]=new triangle(a,b);//动态分配对象
	for(i=0;i<5;i++)
	{
		p[i]->printname();
		t+=p[i]->printarea();
		delete p[i];//释放,隐含了对析构函数的调用
	}
	cout<<"总面积:"<<t<<endl;   
	return 0;
}

纯虚函数与基类指针数组的应用

2.、抽象宠物类的实现
题目内容:
定义抽象宠物类Pet,其中数据成员包括:名字,年龄和颜色;成员函数包括:构造函数;获取成员数据值的函数;纯虚函数Speak和纯虚函数GetInfo; 定义Pet的派生类Cat和Dog,其中Speak函数分别显示猫和狗的叫声,而GetInfo函数分别输出Cat和Dog的属性。主函数中定义Pet指针变量,分别指向动态生成的Cat和Dog对象,并通过指针分别调用GetInfo函数和Speak函数,观察并分析输出结果。

输入格式:
猫和狗的信息

输出格式:
请参考输出样例,严格遵照格式要求输出,建议直接复制样例中的部分文字粘贴进自己的代码中.(冒号是英文冒号,冒号后无空格)

输入样例:
mikey 2 blue
benben 1 black

输出样例:
猫的名字:mikey
猫的年龄:2
猫的颜色:blue
猫的叫声:miao!miao!
狗的名字:benben
狗的年龄:1
狗的颜色:black
狗的叫声:wang!wang!

#include<iostream>
using namespace std;
class pet
{
protected:
	char name[10],color[10];
	int age;
public:
	pet(char Name[10],int Age,char Color[10]){strcpy(name,Name);age=Age;strcpy(color,Color);cout<<"pet类构造函数调用完毕"<<endl;}
    virtual ~pet(){cout<<"pet类析构函数调用完毕"<<endl;}
	char*getname(){return name;}
	char*getcolor(){return color;}
	int getage(){return age;}
	virtual void speak()=0;
	virtual void getinfo()=0;
};
class cat:public pet
{
public:
	cat(char Name[10],int Age,char Color[10]):pet(Name,Age,Color){cout<<"cat类构造函数调用完毕"<<endl;}
	virtual ~cat(){cout<<"cat类析构函数调用完毕"<<endl;}
    virtual void speak()
	{cout<<"猫的叫声:miao!miao!"<<endl;}
    virtual void getinfo()
	{	
		cout<<"猫的名字:"<<getname()<<endl;
		cout<<"猫的年龄:"<<getage()<<endl;
		cout<<"猫的颜色:"<<getcolor()<<endl;
	}
};
class dog:public pet
{
public:
	dog(char Name[10],int Age,char Color[10]):pet(Name,Age,Color){cout<<"dog类构造函数调用完毕"<<endl;}
	virtual ~dog(){cout<<"dog类析构函数调用完毕"<<endl;}
    virtual void speak()
	{cout<<"狗的叫声:wang!wang!"<<endl;}
    virtual void getinfo()
	{
		cout<<"狗的名字:"<<getname()<<endl;
		cout<<"狗的年龄:"<<getage()<<endl;
		cout<<"狗的颜色:"<<getcolor()<<endl;
	}
};
int main()
{
	pet *p;
	char name[10],co[10];
	int age;
	cin>>name>>age>>co;
	p=new cat(name,age,co);
	p->getinfo();
	p->speak();
	cin>>name>>age>>co;
	p=new dog(name,age,co);
	p->getinfo();
	p->speak();
	return 0;
}

纯虚函数与基类指针数组的应用