【项目1】下面的程序存在编译错误。有两种方法可以修改,请给出这两种修改方案,在报告中说明你倾向于用哪一种?为什么?处理此类问题的原则是什么?
- #include<iostream>
- #include<stdlib.h>
- using namespace std;
- class C
- {
- private:
- int x;
- public:
- C(int x){this->x = x;}
- int getX(){return x;}
- };
- int main()
- {
- const C c(5);
- cout<<c.getX();
- return 0;
- }
- //下面是自己的代码
#include<iostream> #include<stdlib.h> using namespace std; class C { private: int x; public: C(int x){this->x = x;} int getX()const {return x;} }; int main() { const C c(5); cout<<c.getX(); return 0; } //可以将getX定义为常量函数,因为他不会修改数据x的值,即可被常对象调用,也可以被非常对象调用。
【项目2-程序填空】按要求将缺少的代码填进去,经调试确认符合要求
a. 用指针访问对象
- class A
- {
- private:
- int a;
- public:
- A() {a=0;}
- ___(1)___{} //定义构造函数,用参数aa初始化数据成员a
- };
- int main()
- {
- ___(2)___; //定义类A的指针对象p
- ___(3)__; //用p指向动态对象并初始化为整数
- return 0;
- }
- //下面是自己的代码
#include <iostream> using namespace std; class A { private: int a; public: A() {a=0;} A(int aa):a(aa) {}//___(1)___{} //定义构造函数,用参数aa初始化数据成员a void show(){cout<<a<<endl;} }; int main() { A *p;//___(2)___; //定义类A的指针对象p p=new A(10);//___(3)__; //用p指向动态对象并初始化为整数 p->show(); return 0; } //p=new A(10);凭感觉写的感觉不错....
b. 指针类型作为成员函数的参数
- class A
- {
- private:
- int *a;
- int n;
- int MaxLen;
- public:
- A(): a(0), n(0), MaxLen(0) {}
- A(int *aa, int nn, int MM);
- ~A();
- int GetValue(int i) {return a[i];}
- };
- A::A(int *aa, int nn, int MM)
- {
- n=nn;
- MaxLen=MM;
- if(n>MaxLen) exit(1);
- a=new int[MaxLen];
- ___(1)___; //以i为循环变量把aa数组中每个元素值传送给a数组的对应元素中
- }
- ___(2)___ //析构函数的类外定义,释放指针型数据a所指向的空间
- int main()
- {
- int b[10]={1,2,3,4,5,6,7,8,9,10};
- A r(b,10,10);
- int i,s=0;
- ___(3)___ ; //以i为循环变量,把r对象的a数据成员中的每个元素值依次累加到s中
- cout<<"s="<<s<<endl;
- return 0;
- }
- //下面是自己的代码
#include <iostream> using namespace std; class A { private: int *a; int n; int MaxLen; public: A(): a(0), n(0), MaxLen(0) {} A(int *aa, int nn, int MM); ~A(); int GetValue(int i) {return a[i];}//指针变量名和数组名的相同性! }; A::A(int *aa, int nn, int MM) { n=nn; MaxLen=MM; if(n>MaxLen) exit(1);//exit(1)强制退出程序,第一次见. a=new int[MaxLen]; //___(1)___; //以i为循环变量把aa数组中每个元素值传送给a数组的对应元素中 for(int i=0;i<MaxLen;++i){ a[i]=aa[i]; } } //___(2)___ //析构函数的类外定义,释放指针型数据a所指向的空间 A::~A(){delete []a;} int main() { int b[10]={1,2,3,4,5,6,7,8,9,10}; A r(b,10,10); int i,s=0; //___(3)___ ; //以i为循环变量,把r对象的a数据成员中的每个元素值依次累加到s中 for(i=0;i<10;++i) s+=r.GetValue(i); cout<<"s="<<s<<endl; return 0; }
【项目3】设计平面坐标点类,计算两点之间距离、到原点距离、关于坐标轴和原点的对称点等
- 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(char style)const;//style取'x','y'和'o'分别表示按x轴, y轴, 原点对称
- void input(); //以x,y 形式输入坐标点
- void output(); //以(x,y) 形式输出坐标点
- };
- //下面是自己的代码
#include <iostream> #include<cmath> using namespace std; 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(char style)const;//style取'x','y'和'o'分别表示按x轴, y轴, 原点对称 void input(); //以x,y 形式输入坐标点 void output(); //以(x,y) 形式输出坐标点 }; CPoint::CPoint(double xx,double yy){x=xx;y=yy;} double CPoint::Distance(CPoint p) const{ return sqrt((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)); } double CPoint::Distance0()const{ return sqrt(x*x+y*y); } CPoint CPoint::SymmetricAxis(char style)const{ CPoint p; switch(style){ case 'x':p.x=x;p.y=-y;break; case 'y':p.x=-x;p.y=y;break; case 'o':p.x=-x;p.y=-y;break; } return p; } void CPoint::input(){ double xx,yy; cout<<"请输入x和y的值:"; cin>>xx>>yy; x=xx;y=yy; } void CPoint::output(){ cout<<"该坐标点是:("<<x<<","<<y<<")"<<endl; } int main(){ CPoint p1(1,1),p2(2,2); const CPoint p3(3,3); p1.output(); cout<<"p1到原点的距离是:"<<p1.Distance0()<<endl; p2.output();cout<<"p2到原点的距离是:"<<p2.Distance0()<<endl; cout<<"p3到原点的距离是:"<<p3.Distance0()<<endl; cout<<"p3和p2之间的距离是:"<<p3.Distance(p2)<<endl; CPoint temp; temp=p3.SymmetricAxis('x');//对象是可以直接赋值的!!! cout<<"p3关于x轴的对称点是:"; temp.output(); return 0; }
【项目4】设计一个三角形类,能够输入三角形的三个顶点,求出其面积、周长,并判断其是否为直角三角形和等腰三角形。
提示:(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; //三顶点
- };
- //下面是自己的代码
#include <iostream> #include<cmath> using namespace std; class CPoint{ private: double x,y; public: CPoint(double xx,double yy):x(xx),y(yy){} double Distancep(CPoint p); }; double CPoint::Distancep(CPoint p){ return sqrt((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)); } class CTriangle { public: CTriangle(CPoint &X,CPoint &Y,CPoint &Z); //给出三点的构造函数 void setTriangle(CPoint &X,CPoint &Y,CPoint &Z);// double perimeter(void);//计算三角形的周长 double area(void);//计算并返回三角形的面积 bool isRightTriangle(); //是否为直角三角形 bool isIsoscelesTriangle(); //是否为等腰三角形 private: CPoint A,B,C; //三顶点 double a,b,c;//三条边 }; CTriangle::CTriangle(CPoint &X,CPoint &Y,CPoint &Z):A(X),B(Y),C(Z){ a=A.Distancep(B); b=B.Distancep(C); c=C.Distancep(A); } double CTriangle::perimeter(){ return a+b+c; } double CTriangle::area(){ double p=perimeter()/2; return sqrt(p*(p-a)*(p-b)*(p-c)); } bool CTriangle::isRightTriangle(){ if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+a*a==c*c) return true; return false; } bool CTriangle::isIsoscelesTriangle(){ if(a==b||b==c||a==c) return true; return false; } int main(){ CPoint A(0,0),B(0,3),C(4,0); CTriangle T1(A,B,C); cout<<"此三角形的周长是:"<<T1.perimeter()<<endl; cout<<"此三角形的面积是:"<<T1.area()<<endl; if(T1.isRightTriangle()) cout<<"这是一个直角三角形!"<<endl; if(T1.isIsoscelesTriangle()) cout<<"这是一个等腰三角形!"<<endl; }
【项目6】设计一个工资类(Salary),其中的数据成员包括职工人数(number,人数不定)和这些职工的工资salary,要求输入职工工资并逐个输出。
提示1:第4周项目5 数组作数据成员曾经处理过类似问题,但固定大小的数组,可能造成空间的浪费,也可能会由于空间不够而不能处理职工人数过多的应用。第4周项目5的扩展1使用指针类型的成员,通过动态分配空间解决了这一问题,但对内存空间的使用上不严谨。这个项目要求做到最终的解决。
提示2:本项目与本周第一部分“阅读程序”中的程序(d)、第二部分上机实践“项目2-程序填空”所体验的知识点相同。
部分源程序如下:
- 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;
- }
- //下面是自己的代码
#include <iostream> using namespace std; class Salary { public: Salary(int n); //n为职工人数,初始化时完成空间的分配 ~Salary(); //析构函数中释放初始化时分配的空间 void input_salary(); void show_salary(); private: double *salary; int number; }; //下面定义类的成员函数 Salary::Salary(int n):number(n){salary=new double[number];} void Salary::input_salary(){ for(int i=0;i<number;++i){ cout<<"请输入第"<<i+1<<"个工人的工资"; double sal; cin>>sal; salary[i]=sal; } } void Salary::show_salary(){ for(int i=0;i<number;++i){ cout<<"第"<<i+1<<"个工人的工资是:"<<salary[i]<<endl; } } Salary::~Salary(){delete []salary;} //下面是测试函数 int main() { Salary s(3); s.input_salary(); s.show_salary(); return 0; }