南京邮电大学C++实验(三)多态性实验(仅参考)

实验名称:类和对象的定义及使用

一、实验目的和要求

(1)熟悉类的设计、运用继承与派生机制设计派生类,合理设置数据成员和成员函数。

(2)掌握双目运算符、单目运算符的重载方法,对常用算术运算符能在自定义类中通过友元函数、成员函数进行重载,以实现静态多态性。

(3)掌握通过继承、虚函数、基类的指针或引用实现动态多态性的方法。

(4)理解并掌握有纯虚函数的抽象类的作用,在各派生类中重新定义各纯虚函数的方法,以及此时实现的动态多态性。

二、实验环境(实验设备)

硬件:  微型计算机

软件:  Windows 操作系统、Microsoft Visual Studio 2010

三、实验原理及内容

实验题目1定义点类Point,有两个double 类型的数据成员x 和y,分别表示横坐标和纵坐标,要求完成如下内容。

(1)定义坐标默认值为原点(0.0,0.0)的构造函数。

(2)以成员函数形式重载:前置“++”运算符和双目运算符“−”。

(3)用友元函数形式重载:双目运算符“+”(两种版本,详见实验指导部分)、插入运算符。

(4)先根据main()主函数代码和运行结果,补充类的定义和相关函数的定义,写出完整程序。

(5)程序正确后,删除main()函数体,根据运行结果,自己重新完成main()函数。

main()主函数代码如下:

int main()

{

        Point pt1(10.5,20.8),pt2(-5.3,18.4),pt3;

        cout<<"original pt1,pt2,pt3 are:\n";

        cout<<pt1<<pt2<<pt3;

        pt3=pt1+100.8;

        cout<<"after pt3=pt1+100.8, pt3 is:"<<pt3;

        pt3=pt1+pt2;

        cout<<"after pt3=pt1+pt2, pt3 is:"<<pt3;

        pt3=++pt1;

        ++pt2;

        cout<<"after ++ pt1,pt2,pt3 are:\n";

        cout<<pt1<<pt2<<pt3;

        pt3=pt1-pt2;

        cout<<"after pt3=pt1-pt2, pt3 is:"<<pt3;

        return 0 ;

}

程序运行结果如下。

original pt1,pt2,pt3 are:

(10.5,20.8)

(-5.3,18.4)

(0,0)

after pt3=pt1+100.8, pt3 is:(111.3,121.6)

after pt3=pt1+pt2, pt3 is:(5.2,39.2)

after ++ pt1,pt2,pt3 are:

(11.5,21.8)

(-4.3,19.4)

(11.5,21.8)

after pt3=pt1-pt2, pt3 is:(15.8,2.4)

实验解答:

(1)类Point的构造函数:

Point(double x0 = 0, double y0 = 0);
Point::Point(double x0, double y0)
{
    x = x0;
    y = y0;
}

(2)用成员函数重载:前置“++”运算符和双目运算符“−”:

Point Point::operator ++() //前置“++”运算符
{
    ++x;
    ++y;
    return *this;
}
Point Point::operator -(const Point& a) //双目运算符“−”
{
    Point temp;
    temp.x = x - a.x;
    temp.y = y - a.y;
    return temp;
}

(3)用友元函数形式重载:双目运算符“+”(两种版本,详见实验指导部分)

Point operator + (const Point& a, const Point& b)
{
    Point temp;
    temp.x = a.x + b.x;
    temp.y = a.y + b.y;
    return temp;
}
Point operator+(const Point& a, double n)
{
    Point temp;
    temp.x = a.x + n;
    temp.y = a.y + n;
    return temp;
}

(4)友元函数重载插入运算符:

ostream& operator<<(ostream& out, const Point& point)
{
    out << "(" << point.x << ", " << point.y << ")" << endl;
    return out;
}

(5)程序正确后,根据运行结果,重新完成的main()函数:

int main()
{
    Point pt1(10.5, 20.8), pt2(-5.3, 18.4), pt3;
    cout << "original pt1,pt2,pt3 are:\n";
    cout << pt1 << pt2 << pt3;
    pt3 = pt1 + 100.8;
    cout << "after pt3=pt1+100.8, pt3 is:" << pt3;
    pt3 = pt1 + pt2;
    cout << "after pt3=pt1+pt2, pt3 is:" << pt3;
    pt3 = ++pt1;
    ++pt2;
    cout << "after ++ pt1,pt2,pt3 are:\n";
    cout << pt1 << pt2 << pt3;
    pt3 = pt1 - pt2;
    cout << "after pt3=pt1-pt2, pt3 is:" << pt3;
    return 0;
}

实验题目2: 定义一个抽象类容器类,其中定义了若干纯虚函数,实现求表面积、体积、输出等功能。由此抽象类派生出正方体、球体和圆柱体等多个派生类,根据需要定义自己的成员变量,在各个派生类中重新定义各纯虚函数,实现各自类中相应功能,各个类成员的初始化均由本类构造函数实现。

① 在主函数中,定义容器类的指针和各个派生类的对象,使指针指向不同对象处调用相同的函数能执行不同的函数代码,从而实现动态多态性。

② 定义一个顶层函数void TopPrint(Container &r);使得主函数中调用该函数时,根据实在参数所有的类自动调用对应类的输出函数。

③ 主函数中定义一个Container类对象,观察编译时的错误信息,从而得出什么结论?

实验解答:

(1)基类Container的定义见实验教材。

(2)各个派生类的定义,根据提示进行填写完整代码:

//正方体类,从Container类公有继承,定义构造函数,重新定义基类的3个纯虚函数

class Cube :public Container
{
protected:
    double length;
public:
    Cube(double l)
    {
       length = l;
    }
    double area()
    {
       return 6 * length * length;
    }
    double volume()
    {
       return length * length * length;
    }
    void print()
    {
       cout << "正方体表面积为" << area() << endl;
       cout << "正方体体积为" << volume() << endl;
    }
};

② //球类,从Container类公有继承,定义构造函数,重新定义基类的3个纯虚函数

class Sphere :public Container
{
public:
    Sphere(double r)
    {
       radius = r;
    }
    double area()
    {
       return 4 * PI * radius;
    }
    double volume()
    {
       return 4.0 / 3 * PI * radius;
    }
    void print()
    {
       cout << "球体表面积为" << area() << endl;
       cout << "球体体积为" << volume() << endl;
    }
};

//圆柱体类,从Container类公有继承,需要增加的成员变量,定义构造函数,重新定义基类的三个纯虚函数

class Cylinder :public Container
{
protected:
    double height;
public:
    Cylinder(double r, double h)
    {
       radius = r;
       height = h;
    }
    double area()
    {
       return 2 * PI * radius * height + radius * radius * 2 * PI;
    }
    double volume()
    {
       return PI * radius * radius * height;
    }
    void print()
    {
       cout << "圆柱体表面积为" << area() << endl;
       cout << "圆柱体体积为" << volume() << endl;
    }
};

(3)正确定义各派生类对象,记录程序的运行结果是:

正方体对象:    Cube cu(2,3); 

球体对象:        Sphere sp(1); 

圆柱体对象:    Cylinder cy(2,6); _

运行结果:

(4)主函数中定义一个Container类对象,编译器的报错信息:

试说明原因:

含有纯虚函数的类是抽象类,无法实例化对象。

实验题目2完整代码:

#include<iostream>
#define PI 3.14
using namespace std;
class  Container
{
protected:
	double radius;
public:
	Container(double r)
	{
		radius = r;
	}
	virtual double area() = 0;
	virtual double volume() = 0;
	virtual void print() = 0;
};
class Cube :public Container
{
protected:
	double length;
public:
	Cube(double l,double radius):Container(radius)
	{
		length = l;
	}
	double area()
	{
		return 6 * length * length;
	}
	double volume()
	{
		return length * length * length;
	}
	void print()
	{
		cout << "正方体" << endl;
		cout << "边长: " << length << endl;
		cout << "正方体表面积为" << area() << endl;
		cout << "正方体体积为" << volume() << endl<<endl;
	}
};
class Sphere :public Container
{
public:
	Sphere(double r):Container(r)
	{
		radius = r;
	}
	double area()
	{
		return 4 * PI * radius *radius ;
	}
	double volume()
	{
		return 4.0* PI * radius*radius*radius/3.0;
	}
	void print()
	{
		cout << "球" << endl;
		cout << "半径: " << radius << endl;
		cout << "球体表面积为: " << area() << endl;
		cout << "球体体积为: " << volume() << endl << endl;
	}
};
class Cylinder :public Container
{
protected:
	double height;
public:
	Cylinder(double radius, double h):Container(radius)
	{
		height = h;
	}
	double area()
	{
		return 2 * PI * radius * height + radius * radius * 2 * PI;
	}
	double volume()
	{
		return PI * radius * radius * height;
	}
	void print()
	{
		cout << "圆柱体" << endl;
		cout << "高度: " << height << " 半径: " << radius << endl;
		cout << "圆柱体表面积为" << area() << endl;
		cout << "圆柱体体积为" << volume() << endl;
	}
};
int main()
{
	Container* p;
	//Container co(3); 
    //定义的Containe类对象
	Cube cu(2,3);
	Sphere sp(1);
	Cylinder cy(2,6);
	p = &cu;
	p->print();
	p = &sp;
	p->print();
	p = &cy;
	p->print();
	return 0;
}

四、实验小结(包括问题和解决方法、心得体会、意见与建议等)

(一)实验中遇到的主要问题及解决方法

1.在题目(1)中在主函数中定义Container类的对象,会产生报错信息,解释原因。

含有纯虚函数的类是抽象类,无法实例化对象。

2. 在题目(2)中通过代码验证,请总结友元函数与成员函数在实现重载时的区别。

(1)形参个数不同。(友元函数比成员函数多一个参数)
(2)类外定义时声明部分有区别。
(3)显示方式的调用不同。
(4)第一运算对象不同。(成员函数第一运算对象是本对象)
(5)第二运算对象有区别。

3.请总结前置++与后置++在实现重载时的不同

前置++无需无用参数 int,而后置++需要,前置++无需定义一个临时变量,而后置++需要保存修改前的值以显现后置++的效果

4.其它问题及解决方法:

(二)实验心得

       通过本次实验,掌握了双目运算符、单目运算符的重载方法,对常用算术运算符能在自定义类中通过友元函数、成员函数进行重载,以实现静态多态性。理解了有纯虚函数的抽象类的作用,在各派生类中重新定义各纯虚函数的方法,以及此时实现的动态多态性。

(三)意见与建议(没有可省略)
  • 20
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲤鱼Louis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值