课程主页在:http://blog.csdn.net/sxhelijian/article/details/11890759,由课程主页,可以看到完整教学方案,所有参考解答
【项目1-深复制体验】
1、阅读下面的程序,补足未完成的注释
#include<iostream> #include<cstring> using namespace std; class A { private: char *a; public: A(char *aa) { a = new char[strlen(aa)+1]; //(1)这样处理的意义在于:______________________________ strcpy(a,aa); //(2)数据成员a与形式参数aa的关系:___________________________________ } ~A() { delete []a; //(3)这样处理的意义在于: ___________________________________________ } void output() { cout<<a<<endl; } }; int main(){ A a("good morning, code monkeys!"); a.output(); A b("good afternoon, codes!"); b.output(); return 0; }
2、将注释(1)所在的那一行去掉,会出现什么现象?为什么?为什么a数据成员所占用的存储空间要在aa长度基础上加1?
3、为类A增加复制构造函数,用下面的main函数测试
int main(){ A a("good morning, code monkeys!"); a.output(); A b(a); b.output(); return 0; }
【项目2-再一个深复制】
下面的程序,因为存在指针类型的数据成员,需要能完成深复制的构造函数。请补充完整构造函数和析构函数(其他不必动)。其中,构造函数要完成下面三个任务:
(1)为各成员函数赋值,其中arrayAddr应该是为保存数据新分配的连续空间的首地址;
(2)将a指向的数组中的数值,逐个地复制到新分配的空间中
(3)getMax( )函数采取的策略是直接返回max,计算max的工作,由构造函数完成
#include<iostream> using namespace std; class A { private: int *arrayAddr;//保存一个有len个整型元素的数组的首地址 int len; //记录动态数组的长度 int max; //动态数组中的最大值(并非动态数组中必须要的数据成员) public: A(int *a, int n); ~A(); int getValue(int i); //获得a指向的数组中下标为i的元素的值 int getLen(); //返回数组长度 int getMax( ); //返回数组中的最大值 }; int A::getValue(int i){ //获得a指向的数组中下标为i的元素的值 return arrayAddr[i]; } int A::getLen(){ //返回数组长度 return len; } int A::getMax( ) { //返回数组中的最大值 return max; } int main(){ int b[10]= {75, 99, 90, 93, 38, 15, 5, 7, 52, 4}; A r1(b,10); cout<<"最大值:"<<r1.getMax()<<endl; int c[15] = {18,68,10,52,3,19,12,100,56,96,95,97,1,4,93}; A r2(c,15); int i,s=0; for(i=0; i<r2.getLen(); i++) s+=r2.getValue(i); cout<<"所有元素的和为:"<<s<<endl; return 0; }
【项目3-成员函数、友元函数和一般函数有区别】
阅读下面的程序,仔细阅读注释。然后模仿完成求点类中距离的任务。
//例:使用成员函数、友元函数和一般函数的区别 #include <iostream> using namespace std; class Time { public: Time(int h,int m,int s):hour(h),minute(m),sec(s) {} void display1(); //display1是成员函数 friend void display2(Time &); //display2是友元函数 int getHour(){return hour;} int getMinute(){return minute;} int getSec(){return sec;} private: int hour; int minute; int sec; }; void Time::display1() //成员函数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) //display3是一般函数,dispaly3前不加Time:: { //不能直接访问,只能用公共接口t.getHour()形式访问私有数据成员 cout<<t.getHour()<<":"<<t.getMinute()<<":"<<t.getSec()<<endl; } int main() { Time t1(10,13,56); t1.display1(); //成员函数这样调用:对象名.函数名() display2(t1); //友员函数的调用和一般函数无异(但实现中可以不同) display3(t1); //一般函数的调用 return 0; }
你需要完成的任务是,利用成员函数、友元函数和一般函数,实现三个版本的求两点间距离的函数,并设计main()函数完成测试。
class CPoint { private: double x; // 横坐标 double y; // 纵坐标 public: CPoint(double xx=0,double yy=0):x(xx),y(yy){} ……//请继续写需要的代码 };提示:此项目和例子的区别在于“距离是一个点和另外一个点的距离”,参数个数上有体现。下面是点类的部分代码。
【项目4-友元类】
定义下面两个类的成员函数(为体验友元类,实际上本例并不一定是一个好的设计,将两个类的合并为一个DateTime,日期、时间都处理更好)
class Date; //对Date类的提前引用声明 class Time { public: Time(int,int,int); void add_a_second(Date &); //增加1秒,1秒后可能会到了下一天,乃到下一月、下一年 void display(Date &); //显示时间,格式:月/日/年 时:分:秒 private: int hour; int minute; int sec; }; class Date { public: Date(int,int,int); friend class Time; //Time为Date的友元类 private: int month; int day; int year; }; int main( ) { Time t1(23,59,32); Date d1(12,31,2013); //测试时,再试试Date d1(2,28,2013)会如何 for(int i=0; i<=100; i++) { t1.add_a_second(d1); t1.display(d1); } return 0; } //下面定义两个类中的成员函数,要求不得再增加成员函数 //注意体会在Time的成员函数中可以调用Date类的私有数据成员
【项目5-复数模板类】
阅读P314的例10.1。该例实现了一个复数类,但是美中不足的是,复数类的实部和虚部都固定只能是double型的。可以通过模板类的技术手段,设计Complex,使实部和虚部的类型为定义对象时用的实际类型。
(1)要求类成员函数在类外定义。
(2)在此基础上,再实现减法、乘法和除法
你可以使用的main()函数如下:
int main( ) { Complex<int> c1(3,4),c2(5,-10),c3; //实部和虚部是int型 c3=c1.complex_add(c2); cout<<"c1+c2="; c3.display( ); Complex<double> c4(3.1,4.4),c5(5.34,-10.21),c6; //实部和虚部是double型 c6=c4.complex_add(c5); cout<<"c4+c5="; c6.display( ); //下面测试减法、乘法和除法 …… return 0; }【项目5拓展(选做)-模板类中使用友元函数】
友元函数提供了一种非成员函数访问私有数据成员的途径,模板类使类中的数据成员的类型变得灵活,这两种技术可以结合起来用。要求在项目5的基础上能够支持用友员函数实现的加法。用于测试的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( ); Complex<int> c7; c7=add_complex(c1,c2); //调用友员函数支持加法运算,有两个形参 cout<<"c1+c2="; c7.display( ); Complex<double> c8; c8=add_complex(c4,c5); //调用友员函数支持加法运算,有两个形参 cout<<"c4+c5="; c8.display( ); return 0; }
【项目6-人数不定的工资类】
设计一个工资类(Salary),其中的数据成员包括职工人数(number,人数不定)和number个职工的工资salary,要求输入职工工资并逐个输出。
提示:用固定大小的数组存储number个职工的工资,可能造成空间的浪费,也可能会由于空间不够而不能处理职工人数过多的应用。Salary声明为指针类型的成员,通过动态分配空间,分配正好大小的空间存储数据。
class Salary { public: Salary(int n); //n为职工人数,初始化时完成空间的分配 ~Salary(); //析构函数中释放初始化时分配的空间 void input_salary(); void show_salary(); private: double *salary; int number; }; //下面定义类的成员函数 …… //下面是测试函数 int main() { Salary s(10); s.input_salary(); s.show_salary(); return 0; }
china-pub | 亚马逊 | 京东 当当 | 豆瓣 图灵社区 官方样章下载 |
==================== 迂者 贺利坚 CSDN博客专栏================= |== IT学子成长指导专栏 专栏文章分类目录(不定期更新) ==| |== C++ 课堂在线专栏 贺利坚课程教学链接(分课程年级) ==| ===== 为IT菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 ===== |