一、目的和要求
1.掌握派多态的使用方法
2.掌握抽象基类的实现方法
3.理解派生类与基类的转换
二、具体内容
1.分析并调试下列程序,写出程序输出结果,并解释原因。
class B
{
public:
virtual void f1()
{
cout << "B:f1()" << endl;
}
virtual void f2()
{
cout << "B:f2()" << endl;
}
void g()
{
cout << "B:g()" << endl;
f1();
f2();
}
};
class D :public B
{
public:
virtual void f1()
{
cout << "D:f1()" << endl;
}
virtual void f3()
{
cout << "D:f3()" << endl;
}
void g()
{
cout << "D:g()" << endl;
f1();
f2();
}
};
int main()
{
D d;
D* pd = &d;
B* pb = &d;
B b = d;
b.f1();
b.f2();
b.g();
pb->f1();
pb->f2();
pb->g();
pd->f1();
pd->f2();
pd->f3();
pd->g();
}
运行结果:
基类指针调用虚函数为动态绑定;其他的大多为静态绑定
D d; //派生类对象
D* d1 = &d; //派生类指针指向派生类对象
B* b1 = &d; //基类指针指向派生类对象
B b = d; //派生类对象转换为基类对象
b.f1 (); //静态绑定,基类对象b调用基类的f1()方法
b.f2 (); //静态绑定,基类对象b调用基类的f2()方法
b.g (); //静态绑定,基类对象b调用基类的g()方法
b1->f1 (); //动态绑定,基类f1()为虚函数,派生类重载f1(),基类指针b1调用派生类的f1()方法
b1->f2 (); //派生类没有重载f2()方法,所以基类指针b1调用基类的f2()方法
b1->g (); //g()方法不是虚函数,所以基类指针b1调用基类的g()方法
d1->f1 (); //静态绑定,派生类指针d1调用派生类f1()方法
d1->f2 (); //静态绑定,派生类没有f2(),所以派生类指针d1调用基类f2()方法
d1->f3 (); //静态绑定,派生类指针d1调用派生类f3()方法
d1->g (); //静态绑定,派生类指针d1调用派生类g()方法
2.定义基本图形Shape抽象基类,包含纯虚函数Area()计算图像面积;二维图形抽象基类Shape2D继承Shape类,添加纯虚函数Premeter()计算二维图形周长;三维图形抽象基类Shape3D继承Shape类,增加纯虚函数Volumn()计算三维图形体积[ 附录已给出相应的公式]。根据类视图实现:
1)Shape2D派生类矩形Retangle、圆形Circle、椭圆Ellipse,重写Area()和Premeter()函数;
2)Shape2D派生类球体Sphere、圆柱体Cylinder、圆锥体Cone,重写Area()和Volumn()函数。
3)实现静态类SumofShape计算图形数组的面积、周长和体积之和。(提示:可以利用dynamic_cast<Shape2D*>和dynamic_cast<Shape3D*>分别将Shape类型指针转换为Shape2D和Shape3D指针用于计算面积和体积)
公式:
#include "stdafx.h"
#include "iostream"
#include "math.h"
using namespace std;
const double PI = 3.1415926;
class Shape
{
public:
Shape(){}
~Shape(){}
virtual double Area () = 0;
};
class Shape2D : public Shape
{
public:
virtual double Perimeter () = 0;
};
class Shape3D : public Shape
{
public:
virtual double Volumn () = 0;
};
class Rectangle : public Shape2D
{
public:
Rectangle (double length, double width) {
length_ = length;
width_ = width;
}
~Rectangle () {}
double Area () {
return length_ * width_;
}
double Perimeter () {
return 2 * (length_ + width_);
}
private:
double length_;
double width_;
};
class Ellipse : public Shape2D
{
public:
Ellipse (double ma,double mi) {
ma_ = ma;
mi_ = ma;
}
~Ellipse () {}
double Area () {
return PI * ma_ * mi_;
}
double Perimeter () {
return 2 * PI * mi_ + 4 * (ma_ - mi_);
}
private:
double ma_;
double mi_;
};
class Circle : public Shape2D
{
public:
Circle (double radius) {
radius_ = radius;
}
~Circle (){}
double Area () {
return PI * radius_ * radius_;
}
double Perimeter () {
return 2 * PI * radius_;
}
private:
double radius_;
};
class Sphere : public Shape3D
{
public:
Sphere (double radius) {
radius_ = radius;
}
~Sphere (){}
double Area () {
return 4 * PI * radius_ * radius_;
}
double Volumn () {
return 4/3 * PI * radius_ * radius_ * radius_;
}
private:
double radius_;
};
class Cylinder : public Shape3D
{
public:
Cylinder (double height,double radius) {
height_ = height;
radius_ = radius;
}
~Cylinder (){}
double Area () {
return 2 * PI * radius_ * (radius_ + height_);
}
double Volumn () {
return PI * radius_ * radius_ * height_;
}
private:
double height_;
double radius_;
};
class Cone : public Shape3D
{
public:
Cone (double height,double radius) {
height_ = height;
radius_ = radius;
}
~Cone (){}
double Area () {
return PI * radius_ * (radius_ + sqrt(radius_ + height_));
}
double Volumn () {
return 1/3 * PI * radius_ * radius_ * height_;
}
private:
double height_;
double radius_;
};
class SumofShape
{
public:
SumofShape () {
}
~SumofShape (){}
static double SumofArea (Shape* shape[],int n) {
double c = 0;
for (int i = 0; i < sizeof(shape); i++)
{
c += shape[i]->Area();
}
return c;
}
static double SumofPremeter (Shape* shape[], int n) {
double p = 0;
for (int i = 0; i < sizeof (shape); i++)
{
Shape2D* shape2d;
if (shape2d = dynamic_cast<Shape2D*>(shape[i])) {
p += shape2d->Perimeter ();
}
}
return p;
}
static double SumofVolumn (Shape* shape[], int n) {
double v = 0;
for (int i = 0; i < sizeof (shape); i++)
{
Shape3D* shape3d;
if (shape3d = dynamic_cast<Shape3D*>(shape[i])) {
v += shape3d->Volumn();
}
}
return v;
}
private:
SumofShape () {}
};
int main()
{
Rectangle r (2, 3);
Ellipse e (8, 4);
Circle c (3);
Sphere s (3);
Cylinder cy (3, 5);
Cone co (3, 4);
Shape* sh[] = { &r,&e,&c,&s,&cy,&co };
double sum_a = SumofShape::SumofArea (sh, 6);
double sum_p = SumofShape::SumofArea (sh, 6);
double sum_v = SumofShape::SumofArea (sh, 6);
cout << "面积总和:" << sum_a << "\n周长总和:" << sum_p << "\n体积总和:" << sum_v << endl;
return 0;
}
运行结果: