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

一、 实验目的和要求

(1)熟悉类的设计、运用继承与派生机制设计派生类,合理设置数据成员和成员函数。
(2)掌握双目运算符、单目运算符的重载方法,对常用算术运算符能在自定义类中通过友元函数、成员函数进行重载,以实现静态多态性。
(3)掌握通过继承、虚函数、基类的指针或引用实现动态多态性的方法。
(4)理解并掌握有纯虚函数的抽象类的作用,在各派生类中重新定义各纯虚函数的方法,以及此时实现的动态多态性。

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

硬件: 微型计算机
软件: Windows 操作系统、Microsoft Visual Studio 2010

三、实验原理及内容

(一)实验题目1:

1、题目

定义点类Point,有两个double 类型的数据成员x 和y,分别表示横坐标和纵坐标,要求完成如下内容。
(1)定义坐标默认值为原点(0.0,0.0)的构造函数。
(2)以成员函数形式重载:前置“++”运算符和双目运算符“−”。
(3)用友元函数形式重载:双目运算符“+”(两种版本,详见实验指导部分)、插入运算符。
(4)先根据main()主函数代码和运行结果,补充类的定义和相关函数的定义,写出完整程序。
(5)程序正确后,删除main()函数体,根据运行结果,自己重新完成main()函数。

2、代码
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 ;
}
3、程序运行结果。
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)
4、实验解答过程:
(1) 类Point的构造函数:
Point(double x = 0.0, double y = 0.0)  
{  
	this->x = x;  
 	this->y = y;  
}
(2) 用成员函数重载:前置“++”运算符和双目运算符“−”:
Point Point::operator++()  
{  
this->x++;   
this->y++;  
return *this;  
}  

Point Point::operator-(const Point& point2)  
{  
Point point(this->x -= point2.x, this->y -= point2.y);  
return point;  
} 
(3) 用友元函数形式重载:双目运算符“+”(两种版本,详见实验指导部分)
friend Point operator+(const Point&, double);  
friend Point operator+(const Point&, const Point&);  

Point operator+(const Point& point, double n)  
{  
Point tmpPoint(point.x + n, point.y + n);  
return tmpPoint;  
}  

Point operator+(const Point& point1, const Point& point2)  
{  
	Point point(point1.x + point2.x, point1.y + point2.y);  
	return point;  
} 
(4) 友元函数重载插入运算符:
friend ostream& operator<<(ostream&, const Point&);  

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:

1、题目

定义一个抽象类容器类,其中定义了若干纯虚函数,实现求表面积、体积、输出等功能。由此抽象类派生出正方体、球体和圆柱体等多个派生类,根据需要定义自己的成员变量,在各个派生类中重新定义各纯虚函数,实现各自类中相应功能,各个类成员的初始化均由本类构造函数实现。
① 在主函数中,定义容器类的指针和各个派生类的对象,使指针指向不同对象处调用相同的函数能执行不同的函数代码,从而实现动态多态性。
② 定义一个顶层函数void TopPrint(Container &r);使得主函数中调用该函数时,根据实在参数所有的类自动调用对应类的输出函数。
③ 主函数中定义一个Container类对象,观察编译时的错误信息,从而得出什么结论?

2、 实验解答:
(1)基类Container的定义见实验教材。
(2)各个派生类的定义,根据提示进行填写完整代码:

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

class Cube: public Container  
{  
private:  
double edgeLength;   // 棱长  
public:  
	Cube(double edgeLength, double radius) :Container(radius)  
	{  
 		this->edgeLength = edgeLength;  
	}  
 	double area()  
 	{  
 		return 6 * edgeLength * edgeLength;  
	}  
 	double volume()  
	{  
		return edgeLength * edgeLength * edgeLength;  
	}  
	void print()  
	{  
		cout << "Cube"<< endl;  
		cout << "edgeLength: " << edgeLength << endl;  
		cout << "area: " << area() << endl;  
		cout << "volume: " << volume() << endl << endl;  
	}  
};  

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

class Sphere: public Container  
{  
public:  
	Sphere(double radius): Container(radius)  { }  
 	double area()  
	{  
	return 4 * PI * radius * radius;  
 	}  
	double volume()  
	{  
		return 4.0 / 3.0 * PI * radius * radius * radius;  
	}  
	void print()  
	{  
		cout << "Sphere" << endl;  
		cout << "radius: " << radius << endl;  
		cout << "area: " << area() << endl;  
		cout << "volume: " << volume() << endl << endl;  
	}  
}; 

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

class Cylinder: public Container  
{  
private:  
	double height;  
public:  
 	Cylinder(double height, double r):Container(r)  
	{  
    	this->height = height;  
  	}  
   	double area()  
	{  
      return 2 * PI * radius * radius + 2 * PI * radius * height;  
    }  
  	double volume()  
	{  
        return PI * radius * radius * height;  
	}  
   void print()  
  	{  
		cout << "Cylinder" << endl;  
		cout << "height: " << height << " radius: " << radius << endl;  
		cout << "area: " << area() << endl;  
		cout << "volume: " << volume() << endl << endl;  
	}  
};  
(3)正确定义各派生类对象,记录程序的运行结果是:

① 类的定义
正方体对象:Cube cube(3.0, 1.0);
球体对象:Sphere sphere(1.0);
圆柱体对象:Cylinder cylinder(4.0, 1.0);
② 运行结果:

Cube  
edgeLength: 3  
area: 54  
volume: 27  

Sphere  
radius: 1  
area: 12.566  
volume: 4.18867  
 
Cylinder  
height: 4  radius: 1  
area: 31.415  
volume: 12.566 
(4)主函数中定义一个Container类对象,编译器的报错信息:

不允许使用抽象类类型 “Container” 的对象:

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

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

(中文五号宋体,英文五号Consolas字体,单倍行距)

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

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

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

  1. 通过题目(2),你觉得纯虚函数与抽象类在编程中有什么价值和意义?

(1)、使代码简洁,可读性强。
(2)、纯虚函数、抽象类和多态配合,使得面向对象可跨模块编程。
(3)、抽象类定义了丰富的接口(即虚函数),可以被编写的多个程序重复调用,可以节省存储空间,使用接口可以减少代码运行时出现的错误,在运行多个程序时,也能更有效率的进行。

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

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

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

(二)实验心得

运算符重载部分内容较多,要多加练习。

(三)意见与建议(没有可省略)

  • 11
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
第三章:C语言基础语法 C语言作为一种高级程序设计语言,其基础语法相对来说比较简单,但是也有一些需要注意的细节,下面就来介绍一下C语言基础语法。 1.注释 在C语言中,注释是一种用来解释代码的方式,对于代码的可读性和可维护性都有很大的帮助。在C语言中,有两种注释方式: (1)单行注释 单行注释以"//"开头,注释内容为"//"后面的所有内容,例如: ```c //这是一个单行注释 ``` (2)多行注释 多行注释以"/*"开头,以"*/"结尾,注释内容为"/*"和"*/"之间的所有内容,例如: ```c /* 这是一个多行注释 可以写很多内容 */ ``` 2.标识符 在C语言中,标识符是程序员定义的变量、函数名、数组名等等的名称,标识符必须由字母、数字、下划线组成,且第一个字符必须是字母或下划线。标识符的命名应该具有一定的意义,方便程序的阅读和理解,例如: ```c int age; //定义一个名为age的整型变量 float height; //定义一个名为height的浮点型变量 ``` 3.数据型 在C语言中,数据型用来定义变量的型,C语言中的数据型包括基本数据型和派生数据型。 (1)基本数据型 C语言中的基本数据型包括整型、浮点型、字符型和布尔型,它们分别对应int、float、char和bool这四个关键字。 例如: ```c int age = 18; //定义一个名为age的整型变量,并赋初值为18 float height = 1.75; //定义一个名为height的浮点型变量,并赋初值为1.75 char sex = 'M'; //定义一个名为sex的字符型变量,并赋初值为'M' bool isStudent = true; //定义一个名为isStudent的布尔型变量,并赋初值为true ``` (2)派生数据型 C语言中的派生数据型包括数组、指针、结构体、共用体等等,它们是由基本数据型衍生出来的,具有不同的特点和用途。 例如: ```c int a[5]; //定义一个名为a的整型数组,长度为5 int *p; //定义一个名为p的指向整型的指针变量 struct student { //定义一个名为student的结构体型 int id; char name[20]; int age; }; ``` 4.运算符 C语言中的运算符包括算术运算符、关系运算符、逻辑运算符等等,它们用来对变量进行数学运算、比较大小、判断真假等等操作。 例如: ```c int a = 10, b = 3; int c = a + b; //算术运算符,c的值为13 bool d = a > b; //关系运算符,d的值为true bool e = a && b; //逻辑运算符,e的值为true ``` 5.流程控制语句 在C语言中,流程控制语句用来控制程序的执行流程,包括条件语句、循环语句等等。 (1)条件语句 C语言中的条件语句包括if语句、switch语句等等,用来根据条件来执行不同的代码块。 例如: ```c if (a > b) { printf("a > b"); } else { printf("a <= b"); } switch (score) { case 90: printf("优秀"); break; case 80: printf("良好"); break; default: printf("不及格"); break; } ``` (2)循环语句 C语言中的循环语句包括for循环、while循环、do-while循环等等,用来重复执行某段代码块。 例如: ```c for (int i = 0; i < 10; i++) { printf("%d ", i); } int j = 0; while (j < 10) { printf("%d ", j); j++; } int k = 0; do { printf("%d ", k); k++; } while (k < 10); ``` 以上就是C语言基础语法的介绍,希望大家能够掌握好这些基础知识,为后续的学习打好基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

亦是远方

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

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

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

打赏作者

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

抵扣说明:

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

余额充值