第 8讲 构造函数和析构函数
教学目的与要求:
了解类对象的创建和撤消过程 。
掌握构造函数和析构函数的定义和使用 。
教学内容提要:
1,构造函数;
2,析构函数;
教学重点:构造函数和析构函数的定义和使用 。
教学难点,构造函数的定义和使用 。
教学进度,P61~ P70
教学过程:
在声明对象时,也可以对其数据成员 初始化 。对象数据成员的初始化需要通过类的特殊成员函数来进行,这个成员函数就是 构造函数 。
构造函数 是类的特殊成员函数,用于在声明类的对象时对其进行初始化。
构造函数的函数名 应与类名相同,构造函数中的参数 根据需要可有可无。
不能为其指定返回值类型,甚至连 void也不可以 。
构造函数应被 声明为公有函数,它只能在创建类的对象时由系统自动调用,对对象进行初始化,程序的 其他部分不能调用 。
class Cylinder
{
public:
Cylinder( );
void setcylinder(double r,double h);
例 8-1 圆柱体类构造函数 不带参数 的情形
【 8.1 构造函数 】
double getradius();
double getheight();
double volume();
double surface_area();
private:
double radius;
double height;
};
Cylinder::Cylinder( )
{
radius=5.0;
height=10.0;
}
class Cylinder
{
public:
Cylinder(double r,double h);
void setcylinder(double r,double h);
圆柱体类构造函数 带有参数 的情形例 8-2
double getradius();
double getheight();
double volume();
double surface_area();
private:
double radius;
double height;
};
Cylinder::Cylinder(double r,double h)
{
radius=r;
height=h;
}
在声明对象时,就必须 利用实参对对象进行初始化 。
例如,Cylinder cylinder1(2.0,3.0);
Cylinder cylinder1; //错误,没有提供用于初始化的实参在声明对象时,如果相应的构造函数 没有形参,括号应该 省略 。 (续)
若是声明对象数组,应该采用下述形式:
Cylinder cylinder1[ 3] ={ Cylinder (1.0,2.0),Cylinder(3.0,4.0),Cylinder(5.0,6.0)};
构造函数也可以定义为 内联函数,可以 带默认形参值,也可以 重载 。
//这个程序在 【 例 3 - 9】 的基础上增加了构造函数
//EXAMPLE.H
#include<iosteam.h>
class Cylinder{
public:
Cylinder(){} //构造函数
Cylinder(double r,double h); //构造函数
void setcylinder(double r,double h);
double getradius()
{
return radius;
}
构造函数的 重载 第 1部分说明:对类 Cylinder的构造函数进行了重载。
没有形参,函数体也为空。
有两个形参。
例 8-3
double getheight()
{
return height;
}
double volume();
double surface_area();
private:
double radius;
double height;
};
//EXAMPLE.CPP
#include″EXAMPLE.h″
const double PI=3.1415926;
Cylinder::Cylinder(double r,double h)
{
radius=r;
height=h;
}
第 1部分第 2部分
(续)
void Cylinder::setcylinder(double r,double h)
{
radius=r;
height=h;
}
double Cylinder:,volume()
{
double vol;
vol=PI*radius*radius*height; return vol;
}
double Cylinder::surface_area()
{
double area;
area=2*PI*radius*height+2*PI*radius*radius;
return area;
}
void main()
{
Cylinder cylinder1(5.0,10.0),cylinder2; //声明对象
cylinder2.setcylinder(10.2,15.6);
第 2部分带有两个实参,系统将自动调用第 2个构造函数给对象 cylinder1初始化。
在声明时调用第一个构造函数。
(续)
注 自动生成的默认构造函数 不带任何参数,在函数体内也 没有任何语句,不执行任何操作。
cout<< ″The radius of the first cylinder is:\ t″<<cylinder1.getradius()<<endl;
cout<< ″The height of the first cylinder is:\ t ″<<cylinder1.getheight()<<endl;
cout<< ″The volume of the first cylinder is:\ t ″<<cylinder1.volume()<<endl;
cout<< ″The surface area of the first cylinder is:\ t ″<<cylinder1.surface_area()<<endl;
cout<< ″The radius of the second cylinder is:\ t ″<<cylinder2.getradius()<<endl;
cout<< ″The height of the second cylinder is:\ t ″<<cylinder2.getheight()<<endl;
cout<< ″The volume of the second cylinder is:\ t ″<<cylinder2.volume()<<endl;
cout<< ″The surface area of the second cylinder is:\ t
″<<cylinder2.surface_area()<<endl;
}
第 2部分系统在创建每一个对象时都需要 自动调用相应的构造函数。
其形式如下,类名::类名()
{}
(续)
//EXAMPLE3_13.H
#include<iostream.h>
class A
{
public:
A()
{
cout<<″A() is called″<<endl;
}
A(int x,int y);
private:
int a,b;
};
A::A(int x,int y)
{
a=x;
b=y;
cout<<″A(int x,int y) is called″<<endl;
cout<<″A=″<<a<<′\ t′<<″B=″<<b<<endl;
}
构造函数的调用例 8-4
A() is called
A(int x,int y) is called
A=10 B=10
//EXAMPLE3_13.CPP
#include″EXAMPLE3_13.H″
void main()
{
A a;
A b(10,10);
}
C++类中还有一个 特殊的成员函数,即析构函数。 析构函数 在对象终止时由系统自动调用,以释放分配给对象的内存。析构函数的函数名应为类名前加
,~,,析构函数中没有参数,也不能为之指定返回值类型。
注 一个类内只能声明一个析构函数 。它也是 公有的成员函数 。如果类中没有声明,编译器也会自动生成一个 带空函数体的析构函数 。
【 8.2 析构函数 】
析构函数的执行过程
//EXAMPLE3_14.H
#include<iostream.h>class A
{
public:
A()
{
cout<<″A() is called″<<endl;
}
~ A()
{
cout<<″~ A() is called″<<endl;
}
};
//EXAMPLE3_14.CPP
#include″EXAMPLE3_14.H″
void main()
{
A a;
cout<<″the program will end″<<endl;
}
A() is called
The program wiil end
~ A() is called
例 8-5
只有在定义构造函数时,才可以 带有成员初始化列表 。如果仅仅是声明构造函数原型,则 不能带成员初始化列表 。
成员初始化列表可用于初始化类中的普通数据成员。甚至还是 必须的 (如后面将介绍的常数据成员等)。
class A
{
public:
A (int x):a(x)
{
cout<< ″class A constructing\ t\ t ″<<a<<endl;
}
~ A ()
{
cout<< ″class A destructing ″<<endl;
}
private:
int a;
};
例,8- 6
课堂练习 1
#include<iostream.h>
class student
{ int sage;
public,
student();
student(int);
int GetAge( ){return sage;}
~student( ) {cout<<“Destructorcalled”<<endl;}
};
student::student( )
{ cout<<”DefaultConstructor called.\n”;
sage=0;
}
student::student(int age)
{ cout<<”Constructor called.\n”;
sage=age;
}
void main()
{ student tom,jack(15);
cout<<”Tom is,<<tom.GetAge()<<”years old.”<<endl;
cout<<”Jack is,<jack.GetAge()<<”years old.”<<endl;
}
Default Constructor called.
Constructor called.
Tom is 0 years old.
Jack is 15 years old
Destructor called
Destructor called
课堂练习 2
#include<iostream.h>
#include<string.h>
class Tdate
{
public:
Tdate(int m,int d,int y);
~Tdate() {cout<<”Tdate Destructor called\n”; }
protected:
int moth,day,year;
};
Tdate::Tdate(int m,int d,int y)
{ month=m; day=d; year=y;
cout<<” Tdate constructor called\n”;
}
class student
{ public:
student(char * n,char s,int m,int d,int y):birthday(m,d,y)
{ strcpy(name,n);
sex=s;
cout<<”calling student”<<endl;
}
~student( ) { cout<<”student Destructor called\n”;}
private,char*name;
char sex;
Tdate birthday; //birthday为对象成员,它是 TDate的 对象
};
void main( )
{
student s1(“mike”,’m’,4,1,2000);
student s2(“tom”,’f’,5,19,1976);
}
Tdate Constructor called
calling student
Tdate Constructor called
calling student
student Destructor
Tdate Destructor called
student Destructor
Tdate Destructor called
小结:
1、构造函数的定义和使用
2、析构函数的定义和使用作业:
P106-110
3.15(只写给出程序的运行结果 ),3.20,3.23