C++编程入门--抽象类

题目:编程定义抽象类Shape,由它派生出5个派生类Circle(圆形),Square(正方形),Rectangle(矩形),Trapezoid(梯形),Triangle(三角形)。用虚函数分别计算几种图形的面积,并求他们的和。要求:用基类指针数组,使它每一个元素指向一个派生类对象。

首先,我们来通俗了解一下什么是抽象类,

包含有纯虚函数的类是抽象类

什么又是纯虚函数,在之前的文章我们说过了虚函数,有时在基类中将某一成员函数声明为虚函数,并不是类本身的要求,而是考虑到派生类的需要,在基类中可以只声明一个函数名,具体的功能留给派生类根据需要去实现。
在这这种虚函数只需要在基类中说明函数原型,用来定义继承体系中的同意接口形式,然后在派生类的虚函数中重新定义具体实现代码,这种基类中的虚函数就是纯虚函数,其声明形式为:

virtual 函数类型 函数名(参数表)=0;

关于纯虚函数,有以下几点需要说明:

  1. 纯虚函数没有函数体;
  2. 最后面的"=0"并不表示函数返回值为0,只是形式上的作用,告诉编译系统这是一个纯虚函数。
  3. 这本质上是一个声明语句,所以最后有分号结束。
  4. 纯虚函数只有函数名而不具备函数的功能,不能被调用,它只是通知编译器合理声明了一个纯虚函数,留待在派生类中实现。因此,只有在派生类中定义之后,它才能更具备函数的功能,可以被调用。
  5. 如果在一个类中声明了纯虚函数,而在派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯虚函数。

而抽象类呢:

1、上面说包含有纯虚函数的类为抽象类。由于抽象类常用做基类,通常称为抽象基类。
2、抽象类的主要作用是,通过它为一个类族(即其派生类等)建立一个公共的接口,使它能更有效地发挥其多态特性。
3、抽象类只负责声明这个接口,而接口的实现,即纯虚函数的函数体,要由派生类自己定义。
4、抽象类派生出新的类之后,如果派生类给出其纯虚函数的实现,这个派生类此时便可以定义自己的对象,从而不再是抽象类,否则,这个派生类仍然是一个抽象类。
5、抽象类不能实例化,即不能定义一个抽象类的对象,但是可以声明其指针和引用,通过这个指针或引用,就可以指向访问派生类对象。

此时,我们再来看这道题,首先创建一个抽象基类:

class Shape{           //定义抽象基类Shape
public:
	virtual double Area() = 0;        //求面积函数,声明为纯虚函数
};

没有别的要求,我们直接来进行派生它的五个子类,分别是:
//圆形派生类Circle

class Circle :public Shape{           //圆形派生类Circle
public:
	Circle(double r) :radius(r){}      
	double Area(){
		return 3.14*radius*radius;
	}
private:
	double radius;         //圆半径
};

//正方形派生类Square

class Square :public Shape{          
public:
	Square(double r) :Sradius(r){}
	double Area(){
		return Sradius*Sradius;
	}
private:
	double Sradius;     //正方形边长
};

//矩形派生类Rectangle

class Rectangle :public Shape{        
public:
	Rectangle(double w, double h) :Sweight(w), Shigh(h){}    
	double Area(){
		return Sweight*Shigh;
	}
protected:
	double Sweight, Shigh;      //矩形宽和高
};

//梯形派生类Trapezoid

class Trapezoid :public Shape{      
public:
	Trapezoid(double Swid, double Lwid, double Rhi) :Swidth(Swid), Lwidth(Lwid), Rhigh(Rhi){}   //构造:梯形上底下底和高
	double Area(){
		return 0.5*(Swidth+Lwidth)*Rhigh;
	}
protected:
	double Swidth, Lwidth, Rhigh;      //梯形上下底和高
};

//三角形派生类Triangle

class Triangle :public Shape{         
public:
	Triangle(double w,double h):width(w),height(h){}
	double Area(){
		return 0.5*width*height;
	}
protected:
	double width, height;
};

加上主测试函数,完整代码如下:

//编程定义抽象类Shape,由它派生出5个派生类Circle(圆形),Square(正方形),Rectangle(矩形),Trapezoid(梯形),Triangle(三角形)。
//用虚函数分别计算几种图形的面积,并求他们的和。要求:用基类指针数组,使它每一个元素指向一个派生类对象。
#include<iostream>
using namespace std;
class Shape{           //定义抽象基类
public:
	virtual double Area() = 0;        //求面积函数,声明为虚函数
};
class Circle :public Shape{           //圆形派生类Circle
public:
	Circle(double r) :radius(r){}      
	double Area(){
		return 3.14*radius*radius;
	}
private:
	double radius;
};
//正方形派生类Square
class Square :public Shape{          
public:
	Square(double r) :Sradius(r){}
	double Area(){
		return Sradius*Sradius;
	}
private:
	double Sradius;
};
//矩形派生类Rectangle
class Rectangle :public Shape{        
public:
	Rectangle(double w, double h) :Sweight(w), Shigh(h){}         //构造:矩形宽和高
	double Area(){
		return Sweight*Shigh;
	}
protected:
	double Sweight, Shigh;
};
//梯形派生类Trapezoid
class Trapezoid :public Shape{      
public:
	Trapezoid(double Swid, double Lwid, double Rhi) :Swidth(Swid), Lwidth(Lwid), Rhigh(Rhi){}   //构造:梯形上底下底和高
	double Area(){
		return 0.5*(Swidth+Lwidth)*Rhigh;
	}
protected:
	double Swidth, Lwidth, Rhigh; 
};
//三角形派生类Triangle
class Triangle :public Shape{         
public:
	Triangle(double w,double h):width(w),height(h){}
	double Area(){
		return 0.5*width*height;
	}
protected:
	double width, height;
};
int main(){
	Shape *s[6];       //声明一个基类指针数组
	s[1] = new Circle(2);     
	s[2] = new Square(3);
	s[3] = new Rectangle(3, 4);
	s[4] = new Trapezoid(2, 3, 4);
	s[5] = new Triangle(4, 5);
	cout << "圆的面积为:" << s[1]->Area() << endl;
	cout << "正方形的面积为:" << s[2]->Area() << endl;
	cout << "矩形面积为:" << s[3]->Area() << endl;
	cout << "梯形面积为:" << s[4]->Area() << endl;
	cout << "三角形面积为:" << s[5]->Area() << endl;
	cout << "总面积为:" << s[1]->Area() + s[2]->Area() + s[3]->Area() + s[4]->Area() + s[5]->Area() << endl;
	return 0;
}

运行结果如下:
在这里插入图片描述

1. 创建一个抽象类DataStructure,该包括下面的成员变量和成员函数: 1) 一个成员变量len,表示里面的元素个数最大值 2) 构造函数DataStructure(int l),将len初始化为0 3) 虚析构函数~DataStructure() 4) 纯虚函数Output(),输出DataStructure中的数据 5) 纯虚函数Size(),返回DataStructure中的元素个数 2. 创建DataStructure的一个派生MyString,该包括下面的成员变量和成员函数: 1) 一个成员变量char* data,表示里面的数据 2) 构造函数MyString(int max_size),将MyString初始化为空串,最大元素个数为max_size 3) 析构函数~MyString(),释放相应的数据 4) Input()函数,往MyString输入数据 5) 重载operator+=()函数,实现两个字符串的连接 6) 重定义Output()和Size()函数 3. 创建DataStructure的一个派生MyStack,该包括下面的成员变量和成员函数: 1) 一个成员变量int* data,用于里面的数据 2) 一个成员变量int top,表示最上面的元素下标 3) 构造函数MyStack(int max_size),将MyStack初始化为空栈,最大元素个数为max_size 4) 析构函数~MyStack(),释放相应的数据 5) Push_back(int e)函数,往栈里面压入一个数据e 6) 重定义Output()和Size()函数 4. 编写main函数,测试上面程序的正确性 1) 创建两个MyString的对象str1和str2,分别调用Input函数输入str1和str2,然后分别调用operator+=函数将str2连接到str1的末尾 2) 创建一个MyStack的对象stack,调用Push_back函数输入往stack中输入m(m < max_size)个数据 3) 创建一个长度为3的DataStructure*型的数组,将其3个元素分别指向str1, str2, stack,然后编写for循环调用Size()和Output()函数输出每个元素的大小和内容。 5. 输入输出样例: 1) 输入样例 A promising techni que for checking reachability 4 12 23 34 45 2) 输出样例 47 A promising technique for checking reachability 29 que for checking reachability 4 12 23 34 45
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值