1、熟悉类的定义格式和类中成员的访问权限。
2、构造函数与析构函数的调用时机与顺序。
3、掌握对象的定义以及对象的初始化的时机与方法。
二、实验内容
1、下面程序sy3_1.cpp中用ERROR表明的语句有错,在不删除和增加代码行的情况下,改正错误语句,使其正确运行。
//sy3_1.cpp #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; }
运行结果如下:
修改程序如下:
//sy3_1.cpp #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();//ERROR return 0; }正确程序运行结果如下:
//sy3_2.cpp #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"; } int main() { TPoint p1(4,9); TPoint p2(p1); TPoint p3=p2; cout<<"p3=("<<p3.getx()<<","<<p3.gety()<<")\n"; return 0; }
程序运行结果如下:
在该程序中,将Tpoint类的带有两个参数的构造函数进行修改,在函数体内增添下述语句:
cout<<"Constructor is called.\n";
(1)写出程序的输出结果,并解释输出结果。
程序如下:
//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<<"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);
调试程序会出现什么现象?为什么?如何解决?(提示:对已有的构造函数进行适当修改)结合运行结果分析如何使用不同的构造函数创建不同的对象。
会出现下面现象:
原因:没有定义该类型的构造函数。
解决办法:将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是使用了拷贝构造函数。
(1)将Heapclass *pa1,*pa3改为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 Memory!"<<endl; return 0; } cout<<"Exit main"<<endl; delete pa1; delete pa2; delete pa3; return 0; }
运行结果如下:
编写程序如下:
//sy3_3.cpp #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;} print(){cout<<"length:"<<len<<"width:"<<wid;} private: int len,wid; }; int main() { Rectangle p1; Rectangle p2(4.0,5.0); cout<<"p1的矩形尺寸:"; p1.print(); cout<<"p2的矩形尺寸:"; p2.print(); cout<<"p2周长:"<<p2.Circumference()<<endl; cout<<"p2面积:"<<p2.Area()<<endl; cout<<"p2的长度:"<<p2.getl()<<endl; cout<<"p2的宽度:"<<p2.getw()<<endl; p2.charge(5.0,6.0); cout<<"修改后的矩形尺寸"; p2.print(); return 0; }
程序运行结果如下:
1、类中私有成员的访问权限。
答:只有类中的函数才能访问类中私有成员
2、构造函数与析构函数的调用顺序。
答:在一般情况下,调用析构函数的顺序与调用构造函数的顺序相反;最先被调用的构造函数,其对应的析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。
3、何时进行对象初始化?如何进行?(提示:注意分一般对象与堆对象讨论)
答:一般对象:在对象的创建时对其进行初始化,可以用构造函数或者用拷贝构造函数进行初始化。
四、实验小结
本次实验是关于构造函数与析构函数,首先我们要先熟悉类的定义格式和类中成员的访问权限,然后要了解构造函数与析构函数的调用时机与顺序,最后要掌握对象的定义以及对象的初始化的时机与方法。这次涉及到的程序有点难,想要把每一个程序的理解清楚真的不容易,有些问题只靠自己是无法解决的,不懂的程序我上网查了一些资料,不过太复杂的程序需要更多的时间去弄清楚,这也我知道自己在编程方面的能力还需要很大的提高,接下来的学习中我会努力改变自己的不足之处。