实验八多态和抽象基类


问题一

分析并调试下列程序,写出程序输出结果,并解释原因。

#include <bits/stdc++.h>
using namespace std;
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();
}

代码一

int main(){  
    D d;//派生类对象 
    D* pd = &d;//派生类指针 →派生类对象 
    B* pb = &d;//基类指针 →派生类对象 
    B b = d;//派生类对象转为基类 
    
    b.f1();  //静态,调用基类函数 B:f1() 
    b.f2();  //静态,调用基类函数 B:f2() 
    b.g();   //静态,调用基类函数 B:g() 
    cout << "\n";
    
    pb->f1();  //动态,因为基类 B:f1() 为虚函数,在派生类重载,所以基类指针 pb 调用派生类函数 D:f1() 
    pb->f2();  //基类指针 pb 调用派生类函数 D:f2(),但因为派生类中无 D:f2() 函数,所以调用基类函数 B:f2() 
    pb->g();   //基类中 B:g() 函数不是虚函数,在派生类中不进行重载,所以基类指针 pb 调用基类函数 B:g() 
    cout << "\n";
    
    pd->f1();  //静态,派生类指针 pd 调用派生类函数 D:f1() 
    pd->f2();  //静态,派生类指针 pd 调用派生类函数 D:f2(),但因为派生类中没有函数 D:f2(),所以调用基类函数 B:f2() 
    pd->f3();  //静态,派生类指针 pd 调用派生类函数 D:f3() 
    pd->g();   //静态,派生类指针 pd 调用派生类函数 D:g() 
    return 0;
}
  • 解释使用标注说明。为方便观察进行了分组。

问题二

定义基本图形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 <bits/stdc++.h>
using namespace std;
const double PI = 3.1415926;
//图形的抽象基类 
class Shape{public: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(){length_ = 0; width_ = 0;}
	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(){semimajor_ = 0; seminminor_ = 0;}
	Ellipse(double semimajor, double seminminor){
		semimajor_ = semimajor;
		seminminor_ = seminminor;
	}
	~Ellipse(){ }
	double Area(){
		return PI*semimajor_*seminminor_;
	}
	double Perimeter(){
		return 2*PI*seminminor_ + 4*(semimajor_ - seminminor_);
	}

private:
	double semimajor_;//长半轴 
	double seminminor_;//短半轴 
};

//派生类, 圆; 
class Circle : public Shape2D{
public:
	Circle(){radius_ = 0;}
	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(){radius_ = 0;}
	Sphere(double radius){
		radius_ = radius;
	}
	~Sphere(){ }
	double Area(){
		return 4*PI*radius_*radius_;
	}
	double Volumn(){
		return 4.0/3.0*(PI*radius_*radius_*radius_);
	}
	
private:
	double radius_;
};

//派生类, 圆柱体;
class Cylinder:public Shape3D{
public:
	Cylinder(){height_ = 0; radius_ = 0;}
	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(){height_ = 0; radius_ = 0;}
	Cone(double height, double radius){
		height_ = height;
		radius_ = radius;
	}
	~Cone(){ }
	double Area(){
		return PI*radius_*(radius_ + sqrt(height_*height_ + radius_*radius_));
	}
	double Volumn(){
		return 1.0/3.0*(PI*radius_*radius_*height_);
	}
	
private:
	double height_;
	double radius_;
};

class Sum_of_Shape{//接口 
public:
    //静态函数 计算图形数组面积之和 
    static double Sum_of_Area(Shape* shape[], int n){
		double sum1 = 0;
		for(int i = 0; i < n; i ++){
			sum1 += shape[i]->Area();
		}
		return sum1;
    }
    
    //静态函数 计算图形数组周长之和 
    static double Sum_of_Premeter(Shape* shape[], int n){  
    	double sum2 = 0;
    	for(int i = 0; i < n; i ++){
    		Shape2D* shape2d;
    		if(shape2d = dynamic_cast<Shape2D*>(shape[i])){
    			sum2 += shape2d->Perimeter();
			}
		}
		return sum2;
	}

	//静态函数 计算图形数组的体积之和 
    static double Sum_of_Volumn(Shape* shape[], int n){
		double sum3 = 0;
		for(int i = 0; i < n; i ++){
			Shape3D* shape3d;
			if(shape3d = dynamic_cast<Shape3D*>(shape[i])){
				sum3 += shape3d->Volumn();
			}
		}
		return sum3;
    }
    ~Sum_of_Shape(){ }

private:
    Sum_of_Shape() {} //定义私有构造函数,禁止实例化 
};

int main(){
	Rectangle rectangle(2, 3);
	Ellipse ellipse(8, 4);
	Circle circle(3);
	Sphere sphere(3);
	Cylinder cylinder(3, 5);
	Cone cone(3, 4);

	Shape* shape_array[] = {&rectangle, &ellipse, &circle, &sphere, &cylinder, &cone};
	double sum_of_area_ = Sum_of_Shape::Sum_of_Area(shape_array, 6);
	double sum_of_premeter_ = Sum_of_Shape::Sum_of_Premeter(shape_array, 6);
	double sum_of_volumn_ = Sum_of_Shape::Sum_of_Volumn(shape_array, 6);
	cout << "面积总和:" << sum_of_area_ << "\n周长总和:" << sum_of_premeter_ << "\n体积总和:" << sum_of_volumn_ << "\n";
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值