}
};
主函数源文件为Li1005.cpp,内容如下:
#include"date.h"
voidmain()
{
Dated1;//自动调用构造函数1
Dated2(2010);//自动调用构造函数2
Dated3(2010,10);//自动调用构造函数3
Dated4(2010,10,6);//自动调用构造函数4
d1.ShowDate();
d2.ShowDate();
d3.ShowDate();
d4.ShowDate();
}
运行结果是:
2010.5.1
2010.5.1
2010.10.1
2010.10.6
当然我们可以定义带缺省值的构造函数,将上述构造函数简化,下述程序的功能与上述程序相当:
#include
classDate
{
intYear,Month,Day;
public:
Date(inty=2010,intm=5,intd=1)
//带参数缺省值的构造函数
{
Year=y;Month=m;Day=d;
}
voidShowDate()
{
cout<}
};
voidmain()
{
Dated1,d2(2010),d3(2010,10),d4(2010,10,6);
d1.ShowDate();
d2.ShowDate();
d3.ShowDate();
d4.ShowDate();
}
运行结果与上例一样。
返回ppt讲稿
例10.6定义学生类,利用构造函数初始化数据成员,利用析构函数做清理工作。
#include
#include
classStudent
{
charNum[10];//学号,注意:
用数组实现
char*Name;//姓名,注意:
用指针实现
intScore;//成绩
public:
Student(char*nump,char*namep,intscore)
{
if(nump)//在构造函数中,
{//不需要动态申请Num成员的空间
strcpy(Num,nump);
}
else
strcpy(Num,"");
if(namep)//在构造函数中,
{//需动态申请Name成员的空间
Name=newchar[strlen(namep)+1];
strcpy(Name,namep);
}
elseName=0;
Score=score;
cout<<"ConstructorCalled!
\n";
}
~Student()//在析构函数中,
{//需释放Name成员的空间
if(Name)delete[]Name;
//new[]和delete[]new/delete用于分配和释放单个变量的空间,而new[]/delete[]则用于分配连续多个变量的空间。
用new[]出连续空间后,指针变量“指向”该空间的首地址。
cout<<"DesturctorCalled!
\n";
}
voidShow()
{
cout<cout<cout<}
};
voidmain()
{
Studenta("040120518","George",80);
a.Show();
}
此程序运行结果是:
ConstructorCalled!
//调用构造函数时的输出
040120518
George
80
DesturctorCalled!
//调用析构函数时的输出
返回ppt讲稿
例10.7调用构造函数和析构函数的时机
#include
classDate
{
intYear,Month,Day;
public:
Date(inty=2002,intm=1,intd=1)
{
Year=y;Month=m;Day=d;
cout<<"Constructor:
";
ShowDate();
}
voidShowDate()
{
cout<}
~Date()
{
cout<<"Destructor:
";
ShowDate();
}
};
Dated4(2008,4,4);//全局对象(静态的)
voidfun()
{
cout<<"进入fun()函数!
\n";
staticDated2(2008,2,2);//局部静态对象
Dated3(2008,3,3);//局部动态对象
cout<<"退出fun()函数!
\n";
}
voidmain()
{
cout<<"进入main()函数!
\n";
Dated1(2008,1,1);//局部动态对象
fun();
fun();
cout<<"退出main()函数!
\n";
}
此程序运行结果是:
Constructor:
2008.4.4//调用构造函数,产生d4对象
进入main()函数!
Constructor:
2008.1.1//调用构造函数,产生d1对象
进入fun()函数!
//第1次进入fun()函数,产生下述d2,d3对象
Constructor:
2008.2.2
Constructor:
2008.3.3
退出fun()函数!
//退出fun()函数,撤消d3对象,不撤消d2对象
Destructor:
2008.3.3
进入fun()函数!
//第2次进入fun()函数,再次产生d3对象
Constructor:
2008.3.3
退出fun()函数!
Destructor:
2008.3.3//退出fun()函数,撤消d3对象
退出main()函数!
//退出main()函数,撤消d1,d2,d4对象
Destructor:
2008.1.1
Destructor:
2008.2.2
Destructor:
2008.4.4
返回ppt讲稿
例10.9定义一个“平面坐标点”类,测试拷贝构造函数的调用。
//头文件"point.h"
classPoint
{
intx,y;
public:
Point(inta=0,intb=0)//缺省构造函数
{
x=a;y=b;
}
Point(Point&p);//拷贝构造函数原型说明
~Point()//析构函数
{
cout<}
voidShow()
{
cout<<"Point:
"<}
intGetx()
{returnx;}
intGety()
{returny;}
};
Point:
:
Point(Point&p)//定义拷贝构造函数
{
x=p.x;y=p.y;
cout<}
//文件Li1009.cpp
#include
#include"point.h"
voidmain()
{
Pointp1(6,8),p2(4,7);
Pointp3(p1);//A调用拷贝构造函数
Pointp4=p2;//B调用拷贝构造函数
p1.Show();
p3.Show();
p2.Show();
p4.Show();
}
此程序运行结果是:
6,8Copy-initializationConstructorCalled.
4,7Copy-initializationConstructorCalled.
Point:
6,8
Point:
6,8
Point:
4,7
Point:
4,7
4,7DestructorCalled.//撤销P4
6,8DestructorCalled.//撤销P3
4,7DestructorCalled.//撤销P2
6,8DestructorCalled.//撤销P1
析构函数与构造函数的调用顺序相反
返回ppt讲稿
例10.10不定义拷贝构造函数时,运行出错。
//文件Li1010.cpp
#include
#include
classStudent
{
char*Name;//姓名,注意:
用指针实现
intAge;//年龄
public:
Student(char*namep,intage)//构造函数
{
Age=age;
if(namep)//在构造函数中,需动态申请空间
{
Name=newchar[strlen(namep)+1];
strcpy(Name,namep);
}
elseName=NULL;
}
~Student()//因在构造函数中动态申请了空间,
{//则在析构函数中,需释放空间
if(Name)delete[]Name;
}
voidShow()
{
cout<}
};
voidmain()
{
Studenta("George",20);
Studentb=a;//A
}
此程序运行时出错,原因是:
没有定义类的拷贝构造函数。
系统自动产生的拷贝构造函数如下:
Student:
:
Student(constStudent&s)
{
Name=s.Name;//注意:
地址值直接赋值
Age=s.Age;
}
正确的做法是,定义如下拷贝构造函数:
Student:
:
Student(constStudent&s)
{
Age=s.Age;
if(s.Name)
{
Name=newchar[strlen(s.Name)+1];//C
strcpy(Name,s.Name);
}
elseName=NULL;
}
返回ppt讲稿
例10.11在本例中,使用例10.9中“平面坐标点”类的头文件point.h,测试用对象做函数参数及函数返回值时拷贝构造函数的使用。
#include"point.h"//普通函数,不是类的成员函数
Pointmove(Pointp,intxoffset,intyoffset)
{
intx=p.Getx()+xoffset,y=p.Gety()+yoffset;
Pointp=p1//参数传递时
Point内存临时对象=t。
//返回对象时
Pointt(x,y);
returnt;
}
voidmain()
{
Pointp1(6,8),p2;
p2=move(p1,2,4);
}
此程序运行结果是:
6,8Copy-initializationConstructorCalled.//A
8,12Copy-initializationConstructorCalled.//B
8,12DestructorCalled.//撤消对象t
6,8DestructorCalled.//撤消对象p
8,12DestructorCalled.//撤消内存临时对象
8,12DestructorCalled.//撤消对象p2
6,8DestructorCalled.//撤消对象p1
返回ppt讲稿
例10.13利用构造函数完成类型转换
//文件Li1013.cpp
#include
classComplex
{
doubleReal,Image;
public:
Complex(doublex=0,doubley=0)
{
Real=x;Image=y;
Show();
cout<<"调用了构造函数\n";
}
~Complex()
{
Show();
cout<<"调用了析构函数\n";
}
voidShow()
{
cout<<'('<}
};
voidmain()
{
Complexc1(3,5),c2;//A
c1=8.0;//B等价于c1=Complex(8.0);
c2=Complex(9.0,9.0);//C
}
此程序运行结果是:
(3,5)调用了构造函数//在A行创建c1对象时,
//调用构造函数
(0,0)调用了构造函数//在A行创建c2对象时,
//调用构造函数
(8,0)调用了构造函数
(8,0)调用了析构函数
(9,9)调用了构造函数
(9,9)调用了析构函数
(9,9)调用了析构函数//在程序结束,
//撤消c2对象时,调用析构函数
(8,0)调用了析构函数//在程序结束,
//撤消c1对象时,调用析构函数
返回ppt讲稿
例10.15处理线性表
#include
classListClass
{
int*ListPtr;//指向线性表的指针
intnLen;//线性表的长度
intnElem;//线性表中当前元素的个数
public:
ListClass(intn=10)//构造函数,初始化线性表,
最大长度的缺省值为10
{
nElem=0;
nLen=n;
if(n)
ListPtr=newint[n];
else
ListPtr=0;
}
~ListClass(void)//析构函数
{delete[nLen]ListPtr;}
intElem(int);//重载函数①,在线性表尾增加一个元素
int&Elem(unsignedn)//重载函数②,
返回线性表中第n个元素的引用
{returnListPtr[n];}
intElem(void)//重载函数③,
返回线性表中当前元素的个数
{returnnElem;}
intLen(void)//返回线性表的长度
{returnnLen;}
intGetElem(inti)//返回线性表第i个元素的值
{
if((i>=0)&&(ireturnListPtr[i];
else
{
cout<<"下标越界"<return(-1);
}
}
voidPrint(void);//输出线性表中的所有元素,
在类体外实现
};
intListClass:
:
Elem(intelem)//重载函数①,
在线性表尾增加一个元素
{
if(nElem==nLen)//线性表已满
{
int*newptr;
newptr=newint[nLen+10];//A行,
申请新线性表空间
for(inti=0;inewptr[i]=ListPtr[i];//将原线性表中的元素
拷贝到新线性表中
delete[nLen]ListPtr;//释放原线性表空间
nLen+=10;
ListPtr=newptr;//让指针指向新线性表空间
}
ListPtr[nElem++]=elem;//添加元素
return(nElem);//返回新线性表的元素个数
}
voidListClass:
:
Print(void)//输出线性表中全体元素
{
for(inti=0;icout<cout<}
voidmain(void)
{
ListClasslist(6);
for(inti=0;i<5;i++)
list.Elem(i);//调用重载函数①
cout<<"线性表的长度为:
"<cout<<"线性表的元素个数为:
";
cout<cout<<"线性表的元素为:
";
list.Print();
list.Elem(3u)=100;//调用重载函数②
cout<<"线性表下标为3的元素的值为:
";
cout<list.Elem(20);//调用重载函数①
list.Elem(200);//调用重载函数①
cout<<"现在线性表的长度为:
"<cout<<"现在线性表中的元素个数为:
";
cout<cout<<"线性表的元素为:
";
list.Print();
cout<<"线性表的最后一个元素为:
";
cout<//调用重载函数③
}
程序的运行结果:
线性表的长度为:
6
线性表的元素个数为:
5
线性表的元素为:
01234
线性表下标为3的元素的值为:
100
现在线性表的长度为:
16
现在线性表中的元素个数为:
7
线性表的元素为:
012100420200
线性表的最后一个元素为:
200
返回ppt讲稿
例10.16初始化对象成员。
#include
#include
classPoint//定义“点”类
{
intx,y;
public:
Point(inta=0,in