(七)C++基础 多态和抽象基类

一、目的和要求

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;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值