C02-程序设计基础提高班(C++)第10周上机任务-类和对象之二

简介: 第10周:阅读教材第9章(p263-313),主要内容是构造和析构函数、对象数组、对象指针、共用数据的保护等,完成第10周上机任务;(回到C02-程序设计基础提高班(C++)学习安排)实践任务:【任务1】设计三角形类,通过增加构造函数,使对象在定义时能够进行初始化#include<iostream>using namespace std;class Triangle

10周:阅读教材第9章(p263-313),主要内容是构造和析构函数、对象数组、对象指针、共用数据的保护等,完成第10周上机任务;

(回到C02-程序设计基础提高班(C++)学习安排)


实践任务:

【任务1】设计三角形类,通过增加构造函数,使对象在定义时能够进行初始化

#include<iostream>
using namespace std;
class Triangle
{public:
	float perimeter(void);//计算三角形的周长
	float area(void);//计算并返回三角形的面积
	void showMessage();
private:
	float a,b,c; //三边为私有成员数据
};


void Triangle:: showMessage()
{
	cout<<”三角形的三边长分别为:”<<a<<'\t'<<<<b<<<<'\t'<<<<c<<endl;
	cout<<"该三角形的周长为:"<< perimeter()<<'\t'<<"面积为:"<< area()<<endl<<endl;
}


void main(void)
{
	Triangle Tri1;	//定义三角形类的一个实例(对象)
	Tri1.showMessage();
	Triangle Tri2(7,8,9);	//定义三角形类的一个实例(对象)
	Tri2.showMessage();
}

特别要求:为全面体会构造函数的各种写法,本任务要求提交多个版本的程序,体现出你已经掌握下列知识点:(1)使用带参数构造函数,即Triangle(float x, float y, float z),三边长在调用时由实参直接给出;(2)设计默认构造函数,即不指定参数时,默认各边长为1;(3)使用默认参数的构造函数,不给定实参时,默认边长为1;(4)在构造函数中使用参数初始化表对数据成员初始化。
[ 参考:三角形类中的构造函数 - http://blog.csdn.net/sxhelijian/article/details/7366083 ]

任务1拓展:请自行设计一个矩形类,可以计算长方形的面积、周长、对象线,判断是否是正方形。请用上构造函数。


【任务2】C++中提供了多种基本的数据类型。实际上,这些远不能满足我们的需求,如复数(第10章的例子大多是处理虚数的),再如分数。本任务将设计一个简单的分数类,完成对分数的几个运算。一则巩固基于对象编程的方法,二则也为第10章做运算符重载等积累些感性认识。
任务要求:完成下面类的设计,并在main()函数中自行定义对象,调用各成员函数,完成基本的测试。

class CFraction
{private:
	int nume;  // 分子
	int deno;  // 分母
 public:
	CFraction(int nu=0,int de=1);   //构造函数,初始化用
	void Set(int nu=0,int de=1);    //置值,改变值时用
	void input();				//按照"nu/de"的格式,如"5/2"的形式输入
	void Simplify();				//化简(使分子分母没有公因子)
	void amplify(int n);			//放大n倍,如2/3放大5倍为10/3
	void output(int style=0);		//输出:以8/6为例,style为0时,输出8/6;
								//style为1时,输出4/3;
								//style为2时,输出1(1/3),表示一又三分之一;
								//不给出参数和非1、2,认为是方式0
};

任务2拓展1:上面output(int style=0)中的输出方式style的类型最适合使用自定义的枚举类(见第7章)了,试着改造一下。

[ 参考:分数类(拓展1) - http://blog.csdn.net/sxhelijian/article/details/7366441 ]

任务2拓展2:这个思考题吊一下大家的胃口:设定义了两个分数类的对象,如CFraction c1, c2。如果定义了int i,我们能用cin>>i;在键盘上输入i的值,是否期望用cin>>c1>>c2;输入分数呢?同理,用cout<<c1<<c2;进行输出,可以吗?进一步,用c1+c2得到新的一个分数,用c1/c2实现两个分数的除法,以及其他加、减、比较、求倒数等也是理所当然的。实际上,要自定义分数类,这些直观的基本运算应该要实现,这叫运算符的重载。本任务中用amplify()给出了“放大”运算的一种实现方案,更多内容值得期待地。


【任务3】编写基于对象的程序,求5个长方柱的体积和表面积。长方柱类的数据成员包括长(length)、宽(width)、高(heigth)等。另外:
(1)需要定义长方柱类,5个长方柱采用一个对象数组表示;
(2)前4个长方柱(即数组的前4个元素)要在定义数组时初始化,其中前3个直接给出参数初始化,第4个用默认构造函数初始化;第5个长方柱定义时不初始化,而是由键盘输入长、宽、高赋值;
(3)输出这5个长方柱的体积和表面积;
[ 参考:长方柱类数组 - http://blog.csdn.net/sxhelijian/article/details/7371175 ]

【任务4】设计一个学生类,包括学号(num)和成绩(score)。建立一个对象数组,内放5个学生的数据,要求:
(1)用指针指向数组首元素,输出第1、3、5个学生的信息;
(2)设计一个函数max,用指向对象的指针作函数参数,在max函数中找出5个学生中成绩最高者,并输出其学号。
[ 参考:学生类数组 - http://blog.csdn.net/sxhelijian/article/details/7371223 ]


【任务5】设计平面坐标点类,计算两点之间距离、到原点距离、关于坐标轴和原点的对称点等

enum SymmetricStyle { axisx,axisy,point};//分别表示按x轴, y轴, 原点对称
class CPoint
{private:
	double x;  // 横坐标
	double y;  // 纵坐标
public:
	CPoint(double xx=0,double yy=0);
	double Distance(CPoint p) const;   // 两点之间的距离(一点是当前点,另一点为参数p)
	double Distance0() const;          // 到原点的距离
	CPoint SymmetricAxis(SymmetricStyle style) const;   // 返回对称点
	void input();  //以x,y 形式输入坐标点
	void output(); //以(x,y) 形式输出坐标点
};
[ 参考:设计平面坐标点类 - http://blog.csdn.net/sxhelijian/article/details/7397313 ]

【任务6】设计一个三角形类,能够输入三角形的三个顶点,求出其面积、周长,并判断其是否为直角三角形和等腰三角形。
提示:(1)这个问题需要用到两个类,顶点类参照任务3中的CPoint类;(2)三角形类参考下面CTriangle类的声明;(3)充分利用CPoint类中已有的代码实现;(4)关于三条边的处理,可以增加三个私有属性,在初始化时求出来备用,也可以在需要时计算得到。
class CTriangle
{
public:
	CTriangle(CPoint &X,CPoint &Y,CPoint &Z):A(X),B(Y),C(Z){} //给出三点的构造函数
	void setTriangle(CPoint &X,CPoint &Y,CPoint &Z);//
	float perimeter(void);//计算三角形的周长
	float area(void);//计算并返回三角形的面积
	bool isRightTriangle(); //是否为直角三角形
	bool isIsoscelesTriangle(); //是否为等腰三角形
private:
	CPoint A,B,C; //三顶点
};

[ 参考:用点类作成员的三角形类 - http://blog.csdn.net/sxhelijian/article/details/7397317 ]


【任务7】将任务6的解决用一个项目多个文件的方式实现,其中两个类的声明放在一个.h文件中,每个类的成员函数分别放一个文件,main()函数用一个文件。体会这样安排的优点。
[ 参考:多文件组织三角形类 - http://blog.csdn.net/sxhelijian/article/details/7397334 ]


【任务8】含有静态数据成员和成员函数的Time类:类中所有的对象共有的数据

class Time
{
public:
	Time(int=0,int=0,int=0);
	void show_time( ); //根据is_24和from0,输出适合形式-20:23:5/8:23:5 pm/08:23:05 pm
	void add_seconds(int); //增加n秒钟
	void add_minutes(int); //增加n分钟  
	void add_hours(int); //增加n小时  
	static void change24();  //改变静态成员is_24,在12和24时制之间转换
	static void changefrom0();   //改变静态成员from0,切换是否前导0
 private:
	static bool is_24; //为true时,24小时制,如20:23:5;为flase,12小时制,显示为8:23:5 pm 
	static bool from0; //为true时,前导0,8:23:5显示为08:23:05
	int hour;
	int minute;
	int sec;
};
//下面写出静态成员的初始化及各成员函数的定义
……
int main( ) //运行结果如下图所示
{  }

[ 参考:静态数据成员和静态成员函数 - http://blog.csdn.net/sxhelijian/article/details/7422511 ]

【任务9】阅读下面的程序,仔细阅读注释。然后模仿完成求点类中距离的任务。
//例:使用成员函数、友元函数和一般函数的区别
#include <iostream>
using namespace std;
class Time
{
public:
	Time(int h,int m,int s):hour(h),minute(m),sec(s){}
	void display1(); //成员函数声明
	friend void display2(Time &);  //友元函数声明
	int getHour(){return hour;}
	int getMinute(){return minute;}
	int getSec(){return sec;}
 private:
	int hour;
	int minute;
	int sec;
};
void display3(Time &);  //一般函数声明


void Time::display1()  //成员函数的实现,dispaly1前加Time::
{
	//以hour形式直接访问私有数据成员,实质是this->hour形式
	cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
void display2(Time &t)  //友元函数的实现,dispaly2前不加Time::,并不是类的成员函数
{
	//不是类的成员函数,却可以t.hour的形式直接访问私有数据成员——友元
	cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;
}
void display3(Time &t)  //一般函数的实现,dispaly1前加Time::
{
	//只能用公共接口t.getHour()形式访问私有数据成员
	cout<<t.getHour()<<":"<<t.getMinute()<<":"<<t.getSec()<<endl;
}
int main()
{
	Time t1(10,13,56);
	t1.display1();  //成员函数这样调用
	display2(t1);   //友员函数调用和一般函数无异
	display3(t1);   //一般函数的调用
	system("pause");
	return 0;
}
你需要完成的任务是,利用成员函数、友元函数和一般函数,实现三个版本的求两点间距离的函数,并设计main()函数完成测试。此任务和上例的区别在于“距离是一个点和另外一个点的距离”,参数个数上有体现。下面是点类的部分代码。
class CPoint  
{
private:  
    double x;  // 横坐标  
    double y;  // 纵坐标  
 public: 
    CPoint(double xx=0,double yy=0):x(xx),y(yy){}  
    ……//请继续写需要的代码
};
[ 参考:使用成员函数、友元函数和一般函数- http://blog.csdn.net/sxhelijian/article/details/7422541]

【任务10】阅读P314的例10.1(代码见附)。该例实现了一个复数类,但是美中不足的是,复数类的实部和虚部都固定只能是double型的。可以通过模板类的技术手段,设计Complex,使实部和虚部的类型为定义对象时用的实际类型。
(1)要求类成员函数在类外定义。
(2)在此基础上,再实现减法、乘法和除法
你可以使用的main()函数如下。
int main( )
{
	Complex<int> c1(3,4),c2(5,-10),c3;  
	c3=c1.complex_add(c2);  
	cout<<"c1+c2="; 
	c3.display( );  
	Complex<double> c4(3.1,4.4),c5(5.34,-10.21),c6;  
	c6=c4.complex_add(c5);  
	cout<<"c4+c5="; 
	c6.display( ); 
	system("pause");
	return 0;
}

[ 参考:复数模板类 - http://blog.csdn.net/sxhelijian/article/details/7422933 ]

附:例10.1代码

#include <iostream>
using namespace std;
class Complex   
{
public:
	Complex( ){real=0;imag=0;}     
	Complex(double r,double i){real=r;imag=i;} 
	Complex complex_add(Complex &c2); 
	void display( );   
private:
	double real; 
	double imag; 
};
Complex Complex::complex_add(Complex &c2)
{
	Complex c;
	c.real=real+c2.real;
	c.imag=imag+c2.imag;
	return c;
}   
void Complex::display( )   
{
	cout<<"("<<real<<","<<imag<<"i)"<<endl;
}
int main( )
{
	Complex c1(3,4),c2(5,-10),c3;  
	c3=c1.complex_add(c2);  
	cout<<"c1="; c1.display( );  
	cout<<"c2="; c2.display( ); 
	cout<<"c1+c2="; c3.display( );  
	return 0;
}


目录
相关文章
|
4月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
95 0
|
4月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
173 0
|
6月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
186 12
|
7月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
7月前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
8月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
7月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
132 16
|
8月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
7月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
7月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
362 6