C++ 第九章 关于类和对象的进一步讨论(二)const的用法和指针数据成员

【项目1】下面的程序存在编译错误。有两种方法可以修改,请给出这两种修改方案,在报告中说明你倾向于用哪一种?为什么?处理此类问题的原则是什么?
  1. #include<iostream>  
  2. #include<stdlib.h>  
  3. using namespace std;  
  4. class C  
  5. {  
  6. private:  
  7.     int x;  
  8.  public:  
  9.     C(int x){this->x = x;}  
  10.     int getX(){return x;}  
  11. };  
  12. int main()  
  13. {  
  14.     const C c(5);  
  15.     cout<<c.getX();  
  16.     return 0;  

  17. //下面是自己的代码
  18. #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. 用指针访问对象
    1. class A   
    2. {  
    3. private:  
    4.     int a;  
    5. public:  
    6.     A() {a=0;}  
    7.     ___(1)___{}  //定义构造函数,用参数aa初始化数据成员a  
    8. };  
    9. int main()   
    10. {  
    11.     ___(2)___;  //定义类A的指针对象p  
    12.     ___(3)__;   //用p指向动态对象并初始化为整数  
    13.   return 0;  

    14. //下面是自己的代码
    #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. 指针类型作为成员函数的参数
    1. class A   
    2. {  
    3. private:  
    4.     int *a;   
    5.     int n;   
    6.     int MaxLen;  
    7.  public:  
    8.     A(): a(0), n(0), MaxLen(0) {}  
    9.     A(int *aa, int nn, int MM);  
    10.     ~A();  
    11.     int GetValue(int i) {return a[i];}   
    12. };  
    13. A::A(int *aa, int nn, int MM)  
    14. {  
    15.     n=nn;  
    16.     MaxLen=MM;  
    17.     if(n>MaxLen) exit(1);  
    18.     a=new int[MaxLen];  
    19.     ___(1)___;  //以i为循环变量把aa数组中每个元素值传送给a数组的对应元素中  
    20. }  
    21. ___(2)___   //析构函数的类外定义,释放指针型数据a所指向的空间  
    22.   
    23.   
    24. int main()  
    25. {  
    26.     int b[10]={1,2,3,4,5,6,7,8,9,10};  
    27.     A r(b,10,10);  
    28.     int i,s=0;  
    29.     ___(3)___ ; //以i为循环变量,把r对象的a数据成员中的每个元素值依次累加到s中  
    30.     cout<<"s="<<s<<endl;  
    31.   return 0;  

    32. //下面是自己的代码
    #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】设计平面坐标点类,计算两点之间距离、到原点距离、关于坐标轴和原点的对称点等
    1. class CPoint  
    2. {  
    3. private:  
    4.     double x;  // 横坐标  
    5.     double y;  // 纵坐标  
    6. public:  
    7.     CPoint(double xx=0,double yy=0);  
    8.     double Distance(CPoint p) const;   // 两点之间的距离(一点是当前点,另一点为参数p)  
    9.     double Distance0() const;          // 到原点的距离  
    10.     CPoint SymmetricAxis(char style)const;//style取'x','y'和'o'分别表示按x轴, y轴, 原点对称  
    11.     void input();  //以x,y 形式输入坐标点  
    12.     void output(); //以(x,y) 形式输出坐标点  
    13. }; 
    14. //下面是自己的代码
    #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)关于三条边的处理,可以增加三个私有属性,在初始化时求出来备用,也可以在需要时计算得到。
    1. class CTriangle  
    2. {  
    3. public:  
    4.     CTriangle(CPoint &X,CPoint &Y,CPoint &Z):A(X),B(Y),C(Z){} //给出三点的构造函数  
    5.     void setTriangle(CPoint &X,CPoint &Y,CPoint &Z);//  
    6.     float perimeter(void);//计算三角形的周长  
    7.     float area(void);//计算并返回三角形的面积  
    8.     bool isRightTriangle(); //是否为直角三角形  
    9.     bool isIsoscelesTriangle(); //是否为等腰三角形  
    10. private:  
    11.     CPoint A,B,C; //三顶点  
    12. }; 
    13. //下面是自己的代码
    #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-程序填空”所体验的知识点相同。
    部分源程序如下:
    1. class Salary  
    2. {  
    3. public:  
    4.     Salary(int n);  //n为职工人数,初始化时完成空间的分配  
    5.     ~Salary();  //析构函数中释放初始化时分配的空间  
    6.     void input_salary();    
    7.     void show_salary();  
    8. private:  
    9.     double *salary;  
    10.     int number;  
    11. };  
    12. //下面定义类的成员函数  
    13. ……  
    14. //下面是测试函数  
    15. int main()  
    16. {  
    17.     Salary s(10);  
    18.     s.input_salary();  
    19.     s.show_salary();  
    20.     return 0;  

    21. //下面是自己的代码
    #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;
    }
    


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值