实验三构造与析构函数

实验三  构造函数和析构函数

班级:         学号:            姓名:          成绩:    

一. 实验目的

1.理解构造函数和析构函数作用;

2.掌握各种类型的构造函数和析构函数的使用;

3.掌握构造函数和析构函数的调用顺序。

二. 使用的设备和仪器

计算机+Windows XP +Visual C++6.0

三. 实验内容及要求

1.阅读程序,写出运行结果,然后上机运行,将机器运行结果与人工运行的结果进行比较,并对每一行输出做出分析。

1

#include <iostream>

using namespace std;

class MyClass

{

public:

     MyClass();

     MyClass(int xx);

MyClass(int xx,int yy);

     MyClass(MyClass &);

     void Display();

     void Set(int, int);

     ~ MyClass();

private:

     int x,y;

};

MyClass:: MyClass()

{   

cout<<"执行无参构造函数:" ;

     x=0;y=0;

     cout<<"x="<<x<<"y="<<y<<endl;

}

MyClass:: MyClass(int xx)

{   

cout<<"执行一个参数构造函数:" ;

    x=xx;y=0;

     cout<<"x="<<x<<"y="<<y<<endl;

}

MyClass:: MyClass(int xx,int yy)

{   

cout<<"执行两个参数构造函数:" ;

     x=xx;y=yy;

     cout<<"x="<<x<<"y="<<y<<endl;

}

MyClass:: MyClass(MyClass &a)

{   

cout<<"执行复制构造函数:" ;

     x=a.x;y=a.y;

     cout<<"x="<<x<<"y="<<y<<endl;

}

void MyClass:: Display()

{   

cout<<"执行显示函数:" ;

     cout<<"x="<<x<<"y="<<y<<endl;

}

void MyClass:: Set(int xx=0,int yy=0)

{   

cout<<"执行设置函数:" ;

     x=xx;y=yy;

     cout<<"x="<<x<<"y="<<y<<endl;

}

MyClass:: ~MyClass ()

{   

cout<<"执行析构函数:" ;

cout<<"x="<<x<<"y="<<y<<endl;

}

void main()    //int main

{

MyClass  a(12,34);

   a.Set(20);

a.Display();

MyClass b(a);

b.Display();

MyClass c;

     MyClass d(222);

{

MyClass e(788,453);

d.Display();

}

c.Display();

}

运行结果:

人工预测:

执行两个参数函数构造x=12y=34

执行设置函数:x=20y=0

执行显示函数:x=20y=0

执行无参数函数构造:x=0y=0

执行一个参数函数造:x=222y=0

执行两个参数函数构造:x=788y=453

执行显示函数:x=222y=0

//执行析构函数x=788y=453

 

执行显示函数:x=0y=0

执行析构函数:x=788y=453

执行析构函数:x=222y=0

执行析构函数:x=0y=0

执行析构函数:x=12y=34

运行结果

 

2

#include<iostream>

using namespace std;

class A

{

public:

A(int x=100,double y=1.2){a=x;b=y;}

void show(char *pt) //void show(string pt)

{ cout<<pt<<":"<<endl;

cout<<"a="<<a<<endl;

cout<<"b="<<b<<endl;

}

private:

int a;

double b;

};

void main()      // int main()

{

A obj1,obj2(100,3.5);

obj1.show("obj1");

obj2.show("obj2");

A *p;

p=&obj1;

p->show("p->obj1");

(*p).show("(*p)obj1");

p=&obj2;

p->show("p->obj2");

   (*p).show("(*p)obj2");

p=new A;

p->show("p->new");

delete p;

}

运行结果:

人工运行:

obj1

a=100

b=1.2

Obj2:

a=100

b=3.5

p->obj1

a=100

b=1.2

(*p)obj1

a=100

b=1.2

p->obj2:

a=100

b=3.5

(*p)obj2

a=100

b=3.5

  P->new:

a=100

b=3.5

上机运行:

 

自己写完运行结果后,到环境中运行时发现程序有一点问题,就做了一点修改(上方程序中后面有注释部分就是自己进行的修改)。

 

3

#include <iostream> 

using namespace std;

class Complex

{

public:

Complex();

Complex (double x, double y);

Complex (Complex & c);

~ Complex ();

double GetRel() { return rel;}

double GetImg() { return img;}

private:

double rel, img;

};

Complex::Complex() 

{

rel=0; img=0;

cout<<"缺省构造函数被调用: "; 

  cout<<"("<<rel<<","<<img<<")"<<endl;

}

Complex::Complex(double x, double y) 

{

rel=x; img=y;

cout<<"构造函数被调用:  ("<<rel<<","<<img<<")"<<endl;

}

Complex::Complex(Complex & c)

{

rel = c.rel;

img = c.img;

cout<<"复制构造函数被调用: ";

  cout<<"("<<rel<<","<<img<<")"<<endl;

}

Complex::~ Complex () 

{

cout<<"析构函数被调用:  ("<<rel<<","<<img<<")"<<endl;

}

//函数定义

Complex fun(Complex c)

{

cout<<"在函数 fun()."<<endl;

double x, y;

x=c.GetRel()*10;

y=c.GetImg()+100;

Complex temp(x, y);

return temp;

}

void main()              //int

{

Complex c1(6.8, 98.23),c2;

c2=fun(c1);

cout<<"c2=("<<c2.GetRel()<<",";

cout<<c2.GetImg()<<")"<<endl;

}

运行结果:

人工运行:

构造函数被调用:6.8,98.23

缺省函数被调用:0,0

在函数fun()中.

构造函数被调用:68198.23

析构函数被调用:68,198.23

c2=68,198.23

析构函数被调用:68,198.23

析构函数被调用:0,0

析构函数被调用:6.8,98.23

上机运行:

 

运行比较:对数值的输出没有加();

没有考虑到复值函数的调用;

在函数fun()中后面涉及到两次析构函数的调用,而在c2=68,198.23)后面只有两次析构,对系统何时调用析构还是不懂;

比较郁闷的是为什么没有缺省函数的析构???

2.编写一个Number类,它有两个整型数据成员xy。成员函数包括构造、输入、输出数、设置以及对两个数据进行加、减、乘、除运算。在主函数中,定义不同的Number类对象,并测试以上功能。

程序代码:

  #include<iostream>

3.using namespace std;

4.class Number

5.{

6. private:

7. int x,y;

8. public:

9. void Input();

10. void Set(int a=0,int b=0);

11. void Dispos();

12. void Show();

13.};

14.void Number::Set(int a,int b)

15.{

16. x=a;

17. y=b;

18.}

19.

20.void Number::Show()

21.{

22. cout<<"x="<<x<<"  "<<"y="<<y<<endl;

23.}

24.void Number::Input()

25.{

26. cin>>x;

27. cin>>y;

28.

29.}

30.void Number::Dispos()

31.{

32. cout<<"x*y="<<x*y<<endl;

33. cout<<"x/y="<<x/y<<endl;

34. cout<<"x+y="<<x+y<<endl;

35. cout<<"x-y="<<x-y<<endl;

36.}

37.int main()

38.{

39. Number a;

40. cout<<"plase input x and y:"<<endl;

41. a.Input();

42. a.Show();

43. a.Dispos();

44. a.Set(5,2);

45. cout<<endl;

46. a.Dispos();

47.

48.return 0;

49.}

3.在实验二第2题中增加构造函数和析构函数,在main函数中定义一个存放N个学生信息的对象数组,并定义以下函数完成相应的动能。

Input(Student stu[],int n)——输入N个学生的信息;

Show(Student stu[],int n) ——输出N个学生的信息;

Max(Student stu[],int n)——输出N个学生中成绩最高的学生信息。

代码:

#include<iostream>

#include<string>

#include<iomanip>

const int N=100;

using namespace std;

class Student

{

private:

int num;

string name;

double english,math,c;

public:

void Input();

void Show();

int Are();

    void Set(int x=0,string y="",double z=0,double h=0,double k=0);

~Student(){};

};

void Student::Input()

{

cout<<"学号:";

cin>>num;

cout<<"名字:";

cin>>name;

cout<<"请输入数学,英语,c++成绩:"<<endl;

cin>>math>>english>>c;

}

void Student::Show()

{

cout<<setw(6)<<num<<setw(10)<<name<<setw(6)<<math<<setw(6)<<english<<setw(6)<<c<<endl;

/* cout<<"学号:"<<num<<endl;

cout<<"名字:"<<name<<endl;

cout<<"数学:"<<math<<endl;

cout<<"英语:"<<english<<endl;

cout<<"c++:"<<c<<endl;*/

}

int Student::Are()

{

return (math+english+c)/3;

}

void Student::Set(int x,string y,double z,double h,double k)

{

num=x;

name=y;

english=z;

math=h;

c=k;

}

int Max(Student*a,int n)

{

int m;

for(int i=0;i<n-1;i++)

{

if((a[i].Are()<a[i+1].Are()))

{

m=i+1;

}

}

return m;

}

int main()

{

int n,k;

int i;

Student*stu=new Student[N];

cout<<"请输入学生数:";

cin>>n;

for(i=0;i<n;i++)

{

stu[i].Input();

}

cout<<setw(6)<<"学号" <<setw(10)<<"姓名"<<setw(6)<<"数学"<<setw(6)<<"英语"<<setw(6)<<"c"<<endl;

for(i=0;i<n;i++)

{

stu[i].Show();

}

k=Max(stu,n);

cout<<"成绩最好的信息:"<<endl; 

cout<<setw(6)<<"学号" <<setw(10)<<"姓名"<<setw(6)<<"数学"<<setw(6)<<"英语"<<setw(6)<<"c"<<endl;

 stu[k].Show();

delete[]stu;

return 0;

}

选做题:

4.某单位对员工收入进行管理,创建一个Income类,包含的数据成员编号num、姓名name、工资wage;成员函数包括:

    构造函数

Input()                   输入

Show()                   输出(输出编号、姓名、工资、应缴税额以及实际收入)

SetWage( double  m )      设置工资值

GetTaxrate( )              计算应缴税额

GetIncome( )              计算职工的实际收入

    在主函数中,定义不同的Income类对象,并测试以上功能。

   (其中,计算应缴税额的方式如下。假设该城市个人所得税的税基为2000元,而其征收个人所得税的规定如下:不超过税基免征税,按超过税基部分征收所得税。超过部分在2000以下,征税5%5000元以下,征税10%10000元以下,征税15%10000元以上,征税20%。)

代码:

#include<iostream>

#include<string>

#include<iomanip>

using namespace std;

class Income

{

private:

int num;

string name;

float wage;

public:

void Input();

void Show(Income &);                  

void Set(double m){wage=m;}    

double GetTaxrate(Income&);              

double GetIncome(Income&);

};

void Income::Input()

{

cout<<"编号:";

cin >>num;

cout<<"姓名:";

cin>>name;

cout<<"工资:";

cin>>wage; 

}

void Income::Show(Income &s)

{

cout<<setw(10)<<"编号"<<setw(10)<<"姓名"<<setw(15)<<"工资"<<setw(18)<<"应交税费"<<setw(18)<<"实际收入"<<endl; 

cout<<setw(10)<<s.num<<setw(10)<<s.name<<setw(15)<<s.wage<<setw(18)<<s.GetTaxrate(s)<<setw(18)<<s.GetIncome(s)<<endl;

}

double Income::GetTaxrate(Income&s)

{

double a;

if(s.wage-2000<1)

{

a=0;

}

else if(s.wage-2000<2001)

{

a=(s.wage-2000)*0.05;

}

else if(s.wage-2000<5001)

{

a=2000*0.05+(s.wage-4000)*0.1;

}

else if(s.wage-2000<10000)

{

a=2000*0.05+3000*0.1+(s.wage-7000)*0.15;

}

else if(s.wage-2000>10000)

{

a=2000*0.05+3000*0.1+5000*0.15+(s.wage-12000)*0.2;

}

return a;

}

double  Income::GetIncome(Income &s)

{

double b,a;

a=s.GetTaxrate(s);

b=wage-a;

return b;

}

int main()

{

Income s;

s.Input();

cout<<"员工信息为:"<<endl;

s.Show(s);

cout<<"设置后信息为:"<<endl; 

s.Set(7000);

s.Show(s);

return 0;

}

5.在第3题的基础上,还可以增加以下函数对N个学生平均成绩进行排序的函数

Sort(Student stu[],int n)(上交答案时,该题只交这个函数的代码以及运行结果界面即可。)

#include<iostream>

#include<string>

#include<iomanip>

const int N=100;

using namespace std;

class Student

{

private:

int num;

string name;

double english,math,c;

public:

void Input();

void Show();

int Are();

    void Set(int x=0,string y="",double z=0,double h=0,double k=0);

~Student(){};

};

void Student::Input()

{

cout<<"学号:";

cin>>num;

cout<<"名字:";

cin>>name;

cout<<"请输入数学,英语,c++成绩:"<<endl;

cin>>math>>english>>c;

}

void Student::Show()

{

cout<<setw(6)<<num<<setw(10)<<name<<setw(6)<<math<<setw(6)<<english<<setw(6)<<c<<endl;

}

int Student::Are()

{

return (math+english+c)/3;

}

void Student::Set(int x,string y,double z,double h,double k)

{

num=x;

name=y;

english=z;

math=h;

c=k;

}

int Max(Student*a,int n)

{

int m;

for(int i=0;i<n-1;i++)

{

if((a[i].Are()<a[i+1].Are()))

{

m=i+1;

}

}

return m;

}

void Sort(Student*a,int n)

{

float t;

float b[N];

for(int i=0;i<n;i++)

{

b[i]=a[i].Are();

}

for(int i=0;i<n-1;i++)

{

for(int j=i+1;j<n;j++)

{

if(b[i]<b[j])

t=b[i];

b[i]=b[j];

b[j]=t;

}

}

cout<<"排序为:"<<endl;

for(int i=0;i<n;i++)

{

cout<<b[i]<<endl;

}

}

int main()

{

int n,k;

int i;

Student*stu=new Student[N];

cout<<"请输入学生数:";

cin>>n;

for(i=0;i<n;i++)

{

stu[i].Input();

}

cout<<setw(6)<<"学号" <<setw(10)<<"姓名"<<setw(6)<<"数学"<<setw(6)<<"英语"<<setw(6)<<"c"<<endl;

for(i=0;i<n;i++)

{

stu[i].Show();

}

k=Max(stu,n);

cout<<"成绩最好的信息:"<<endl; 

cout<<setw(6)<<"学号" <<setw(10)<<"姓名"<<setw(6)<<"数学"<<setw(6)<<"英语"<<setw(6)<<"c"<<endl;

 stu[k].Show();

Sort(stu,n);

delete[]stu;

return 0;

}

四. 实验步骤

1、程序代码:

运行结果:

2、程序代码:

运行结果:

五. 实验总结

1.实验中遇到的问题及解决方法

1)调用成员函数时直接Show();没有加对象名;

通过翻阅其他程序发现不同之处。

2)误以为只要首地址加函数就可以对多个对象进行处理:例如定义Student stu=new[100];对对象进行处理直接stu.Show();

这个问题实在不应该有,经过认真思考就能发现问题。计算机那么笨怎么可能识别stu 就算识别没有条件 它又怎么知道何时停止;

3)setw()运用,总是不能使之完全对应,

4)偶尔对私有数据进行访问,但一般都能及时发现,

5)第一题第三个小题:

在函数fun()中后面涉及到两次析构函数的调用,而在c2=68,198.23)后面只有两次析构,对系统何时调用析构还是不懂;

比较郁闷的是为什么没有缺省函数的析构???

2.个人收获和体会

学习c++后,深深体会到它的方便,很多小细节省去了比如输出输入加d%flf%或者是是否用&号,新的东西总会产生新的问题,例如类中涉及到构造和析构,还是不懂何时系统会自动调用它们。

通过这些练习,还是发现自己练习太少,写起程序来还不能做到得心应手,还是会犯一些低级错误,例如少了头文件,分号;return0

这样自己在课下提前做,虽然没有时间限制,不过也逐渐是自己有了那种编程思想,写起来也逐渐顺手起来了。

 

 

猜你喜欢

转载自blog.csdn.net/benben0729/article/details/45618251