实验三

实验目的和要求

  1、熟悉类的定义格式和类中成员的访问权限。

  2、构造函数与析构函数的调用时机与顺序。

  3、掌握对象的定义以及对象的初始化的时机与方法。

实验内容

  1、下面程序sy3_1.cpp中用ERROR标明的语句有错吧,在不删除和增加代码行的情况下,改正错误语句,使其正确运行。

运行程序如下:

#include<iostream>
using namespace std;
class Aa
{
  public:
      Aa(int i=0){a=i;cout<<"Constructor"<<a<<endl;}
      ~Aa(){cout<<"Destructor"<<a<<endl;}
      void print(){cout<<a<<endl;}
  private:
    int a;
};
int main()
{
    Aa a1(1),a2(2);
    a1.print();
   cout<<a2.a<<endl;//ERROR
    return 0;
}
错误如下:
修改程序如下:
#include<iostream>
using namespace std;
class Aa
{
  public:
      Aa(int i=0){a=i;cout<<"Constructor"<<a<<endl;}
      ~Aa(){cout<<"Destructor"<<a<<endl;}
      void print(){cout<<a<<endl;}
  private:
    int a;
};
int main()
{
    Aa a1(1),a2(2);
    a1.print();
    a2.print();
    return 0;
}

运行结果如下:

2、调试下列程序:
#include<iostream>  
using namespace std;  
class TPoint  
{  
public:  
    TPoint(int x=0,int y=0){X=x,Y=y;}  
    TPoint(TPoint &p);  
    ~TPoint(){cout<<"Destructor is called\n";}  
    int getx(){return X;}  
    int gety(){return Y;}  
private:  
    int X,Y;  
};  
TPoint::TPoint(TPoint &p)  
{  
    X=p.X;  
    Y=p.Y;  
    cout<<"Copy-initialization Constructor is called\n";  
}  
int main()  
{  
    TPoint p1(4,9);  
    TPoint p2(p1);  
    TPoint p3=p2;  
    TPoint p4,p5(2);  
    cout<<"p3=("<<p3.getx()<<","<<p3.gety()<<")\n";  
    return 0;  
}  

在程序中,将TPoint类的带有两个参数的构造函数进行修改,在函数体内增添下述语句:

      cout<<"Constructor is called\n";

(1)写出程序的输出结果,并解释输出结果;

程序如下:
#include<iostream>
using namespace std;
class TPoint
{
public:
    TPoint(int x=0,int y=0){X=x,Y=y;}
    TPoint(TPoint &p);
    ~TPoint(){cout<<"Destructor is called\n";}
    int getx(){return X;}
    int gety(){return Y;}
private:
    int X,Y;
};
TPoint::TPoint(TPoint &p)
{
    X=p.X;
    Y=p.Y;
    cout<<"Constructor is called\n";
    cout<<"Copy-initialization Constructor is called\n";
}
int main()
{
    TPoint p1(4,9);
    TPoint p2(p1);
    TPoint p3=p2;
    TPoint p4,p5(2);
    cout<<"p3=("<<p3.getx()<<","<<p3.gety()<<")\n";
    return 0;
}

运行结果如下:

(2)按下列要求进行调试:

       在主函数体内,添加下列说明语句:

      TPoint p4,p5(2);

#include<iostream>  
using namespace std;  
class TPoint  
{  
public:  
    TPoint(int x,int y){X=x,Y=y;}  
    TPoint(TPoint &p);  
    ~TPoint(){cout<<"Destructor is called\n";}  
    int getx(){return X;}  
    int gety(){return Y;}  
private:  
    int X,Y;  
};  
TPoint::TPoint(TPoint &p)  
{  
    X=p.X;  
    Y=p.Y;  
    cout<<"Copy-initialization Constructor is called\n";  
    cout<<"Constructor is called\n";  
}  
int main()  
{  
    TPoint P4,P5(2);  
    TPoint p1(4,9);  
    TPoint p2(p1);  
    TPoint p3=p2;  
    cout<<"p3=("<<p3.getx()<<","<<p3.gety()<<")\n";  
    return 0;  
}  

调试程序会出现什么现象?为什么?如何解决?(提示:对已有的构造函数进行适当修改)结合运行结果分析如何使用不同的构造函数创建不同的对象。

现象:

为什么:因为在类中没有定义不带参数和带一个参数的构造函数;

如何解决:将带两个参数的构造函数改为缺省的构造函数,就是可以将TPoint(int x,int y)改为TPoint(int x=0,int y=0) ; 在运行过程中,TPoint p1(4,9)和TPoint p4,p5(2);调用了构造函数,而TPoint p2(p1)和TPoint p3=p2是使用了拷贝构造函数。如下所示:

//sy3_2.cpp  
#include<iostream>  
using namespace std;  
class TPoint  
{  
public:  
    TPoint(int x=0,int y=0){X=x,Y=y;}  
    TPoint(TPoint &p);  
    ~TPoint(){cout<<"Destructor is called\n";}  
    int getx(){return X;}  
    int gety(){return Y;}  
private:  
    int X,Y;  
};  
TPoint::TPoint(TPoint &p)  
{  
    X=p.X;  
    Y=p.Y;  
    cout<<"Copy-initialization Constructor is called\n";  
    cout<<"Constructor is called\n";  
}  
int main()  
{  
    TPoint P4,P5(2);  
    TPoint p1(4,9);  
    TPoint p2(p1);  
    TPoint p3=p2;  
    cout<<"p3=("<<p3.getx()<<","<<p3.gety()<<")\n";  
    return 0;  
}  

结果:

3、对教材中Li3_11.cpp的主函数做如下修改:

(1)将Heapclass *pa1,*pa2 改为Heapclass *pa1,*pa2,*pa3;

(2)在语句pa2=new Heapclass 后增加语句pa3=new Heapclass(5);

(3)将语句 if(!pa1||!pa2) 改为if(!pa1||!pa2||!pa3)

(4)在语句delete pa2 后增加语句delete pa3;

写出程序的输出结果,并解释输出结果。

程序如下:

#include<iostream>
using namespace std;
class Heapclass
{
public:
   Heapclass(int x);
   Heapclass();
   ~Heapclass();
private:
    int i;
};
Heapclass::Heapclass(int x)
{
    i=x;
    cout<<"Contstructor is called. "<<i<<endl;
}
Heapclass::Heapclass()
{
    cout<<"Default Contstructor is called."<<endl;
}
Heapclass::~Heapclass()
{
 cout<<"Default is called."<<endl;
}
int main()
{
   Heapclass *pa1,*pa2,*pa3;
   pa1=new Heapclass(4);
   pa2=new Heapclass;
   pa3=new Heapclass(5);
   if(!pa1||!pa2||!pa3)
   {
       cout<<"Out of Mcmory!"<<endl;
       return 0;
   }
   cout<<"Exit main"<<endl;
   delete pa1;
   delete pa2;
   delete pa3;
   return 0;
}

运行结果如下:

解释:pa1、pa2、pa3中是2个指向类Heapclass的对象指针,在能够赋给它们足够内存的情况下,使用运算符new给它们赋值,同时对它们所指向的对象进行初始化。使用delete释放这三个指针所指向的对象,由于不能够赋给pa1、pa2或pa3足够内存,所以输出“Out of Memory”。

4、请定义一个矩形类(Rectangle),私有数据成员为矩形的长度(len)和宽度(wid),无参构造函数置len和wid为0,有参构造函数置len和wid为对应形参的值,另外还包括求矩形周长、取矩形面积、取矩形长度和宽度、修改矩形长度和宽度为对应形参的值、输出矩形尺寸等公有成员函数。要求输出矩形尺寸的格式为“length:长度,width:宽度”。
程序如下:
#include<iostream>  
using namespace std;  
class Rectangle  
{  
public:  
   Rectangle()  
   {  
       len=0;  
       wid=0;  
   }  
   Rectangle(double Len,double Wid)  
   {  
       len=Len;  
       wid=Wid;  
    }  
   double Circumference()  
   {  
       return 2*(len+wid);  
    }  
   double Area()  
   {  
       return len*wid;  
    }  
   double getl()  
   {  
       return len;  
    }  
   double getw()  
   {  
       return wid;  
    }  
   void charge(double a,double b)  
   {  
       len=a;  
       wid=b;  
    }  
   void s()  
   {  
       cout<<"length:"<<len<<"  "<<"width:"<<wid<<endl;  
    }  
private:  
    int len,wid;  
};  
int main()  
{  
  Rectangle q;  
  Rectangle h(5.0,2.0);  
  cout<<"q的矩形尺寸:"<<endl;  
  q.s();  
  cout<<"h的矩形尺寸:"<<endl;  
  h.s();  
  cout<<"h的周长:"<<h.Circumference()<<endl;  
  cout<<"h的面积:"<<h.Area()<<endl;  
  cout<<"h的长度:"<<h.getl()<<endl;  
  cout<<"h的宽度:"<<h.getw()<<endl;  
  h.charge(8.0,6.0);  
  cout<<"修改后的矩形的尺寸:"<<endl;  
   h.s();  
   return 0;  
}  

结果如下:


分析与讨论

  1、类中私有成员的访问权限。

    答:私有成员是被隐藏的数据,只有该类的成员函数或友元函数才可以引用它。

  2、构造函数与析构函数的调用顺序。

    答:构造函数在创建对象的时候被调用,析构函数在释放对象的时候被调用,释放由构造函数分配的内存,构造函数与析构函数的调用顺序正好相反。

  3、何时进行对象初始化?如何进行?(提示:注意分一般对象和堆对象讨论)

    答:一般对象:在对象创建时进行初始化,可以用构造函数或拷贝函数进行初始化。

        堆对象:使用运算符new分配内存,调用构造函数来进行初始化。

实验总结

       本次实验要求我们熟悉类的定义格式和类中成员的访问权限,构造函数与析构函数的调用时机与顺序,掌握对象的定义以及对象的初始化的时机与方法等。类和对象比较好掌握,就是构造函数和析构函数我到现在还不太明白,不知道该怎么运用,请教了几位同学,也自己百度了一下,感觉懵懵懂懂的,不过最后还是把实验做完了,相当的不容易。每做一次实验就会成长一次,也会掌握更多的东西,学到了东西感觉很踏实。

阅读更多
文章标签: 我的啊
个人分类: 课后作业
上一篇第三章课后习题
下一篇实验四
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭