C++的面向对象基础(二)

3 构造函数和析构函数

3.1构造函数

在建立一个对象时,常常需要作某些初始化的工作(例如对数据赋予初值),C++提供了一种特殊的成员函数--构造函数(constructor)。这种函数与其他成员不同,不需要用户发“消息”来激活它,而是在建立对象时自动执行。构造函数是由用户定义的,它必须与类名同名,以便系统能识别它并把它作为构造函数。现在我们在前面声明的类中加入构造函数。

class stud

{private: //声明以下部分为私有的

int num;

char name[10];

char sex;

Public:

stud( ) //定义构造函数,函数名与类名相同

(num=10010;

strcpy(name," Wang-li" );

sex='F';} //以上3行为给数据赋初值

void display( ) //定义成员函数

{cout<<"num:"<<num<<endl;

cout<<"name:"<<name<<endl;

cout<<"sex:"<<sex<<endl; }

};

stud stud1: //在定义对象 stud1时自动执行构造函数

注意:构造函数不需用户调用,而是在定义一个对象时由系统自动执行,而且只能执行一次。构造函数一般声明为public,无返回值,也不需加void类型声明。现在写成一个完整的程序。

例15.1 建立一个对象,输出学生的学号、姓名、性别。

# include<string. h>

#include<iostream.h>

void main( )

{ class stud //声明一个类

{private: //私有部分

int num;

char name[10];

char sex ;

Public: //公用部分

stud( ) //定义构造函数,函数名与类名相同

{num=10010; //给数据赋初值

strcpy (name," Wang-li" );

sex='F';} 

void display () //定义成员函数,输出对象的数据

{cout<<"num:"<<num<<endl;

cout<<"name:"<<name<<endl;

cout<<"sex:"<<sex<<endl;}

}

stud stud1; //在定义对象stud1时自动执行构造函数

stud1.display( ); //从对象外面调用display函数

}

可以看到整个程序很简单,它包括三部分:①声明一个类;②定义一个对象;③向对象发出消息,执行对象中的成员函数display。在定义stud1对象时自动执行了构造函数 ud(),因此对象中的数据成员均被赋了值。执行display函数输出以下信息:

num:10010

nome: Wang-li

sex: F

在程序中可以看到只有对象中的函数才能引用本对象中的数据。如果在对象外面直接用

cout<<stud1.num ;

企图输出学生的学号是不行的。由此可体会到类的特点。

如果要建立两个对象,分别对数据赋予初值,就不能这样定义构造函数stud了,因为它会使两个学生的初值相同,例如姓名都是Wang-li。应该分别赋予不同的初值。可将构造函数修改如下:

stud(int n,char nam[],chars ) //定义构造函数,有形参

{num=n;

strcpy(name,nam);

sex=s;

}

此时数据的值不由构造函数stud确定,而是在调用此函数时由实参传来。但应注意构造函数不同于一般的成员函数,不能这样调用:

stud1.stud(10010," Wang-li",'f'); //企图用调用一般成员函数的方法来调用构造函数

前已说明构造函数是在建立对象时调用的,因此实参应该在建立对象时给出。如:

stud stud1(10010,"Wang-li",’f’),stud2(10011,"Zhang-fun",'m');

现在定义了两个对象stud1和stud2,它们的数据初值是不同的。如果想分别输出两个学生的数据,可以用以下的语句:

stud1.display();

stud2.display();

此时的输出如下:

num:10010

name:Wang-li

sex:f

num:10011

name:Zhang-fun

sex:m

用户也可以不定义构造函数,编译系统会自动生成一个构造函数;该函数没有参数,不进行任何操作。

构造函数也可以重载,下面是两个重载函数:

stud( ) //在构造函数中对数据赋初值

{num=10010;

strcpy (name,"Wang-li");

sex='F';

}

stud(int n ,char nam[],char s) //有形参,由实参将值传给形参

{num=n;

strcpy (name,nam);

sex=s;

}

在定义对象时允许有实参和无实参。如:

stud studl; //不带实参,数据初值在构造函数中指定

stud stud2(10011,"Zhang-fun",'m' ); //带实参,数据初值由实参给出

3.2析构函数

析构函数(destructor)与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后”的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。

析构函数名也应与类名相同,只是在函数名前面加一个波浪符~,例如~stud(),以区别于构造函数。它不能带任何参数,也没有返回值(包括void类型)。只能有一个析构函数,不能重载。如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数,它也不进行任何操作。所以许多简单的类中没有用显式的析构函数。

例15.2 包含构造函数和析构函数的C++程序。

# include<string. h>

# include<iostream.h>

class stud //声明一个类

{private: // 私有部分

int num ;

char name[10];

char sex;

public: //公用部分

stud(int n ,char nam[],chars) //构造函数

{num=n;

strcpy(name,nam);

sex=s;}

~stud() //析构函数

{  }

void display ( ) //成员函数,输出对象的数据

{cout<<" num: "<<num<<endl;

cout<<"name: "<<name<<endl;

cout<<"sex: "<<sex<<endl ;}

void main ( )

{

stud stud1(10010,"Wang-li",'f'),stud2(10011,"Zhang-fun",'m'); //建立两个对象

stud1.display( ); //输出学生1的数据

stud2.display( ); //输出学生2的数据

}

现在把类的声明放在main函数之前,它的作用域是全局的。这样做可以使main函数更简练一些。在 main函数中定义了两个对象并且给出了初值。然后输出两个学生的数据。运行结果和例15.1中给出的相同。在本例中,析构函数并无任何实质上的作用,我们把它写出来,只是为了说明析构函数的使用方法。

在本程序中,成员函数是在类中定义的,如果成员函数的数目很多以及函数的长度很长,类的声明就会占很大的篇幅,不利于阅读程序。可以在类的外面定义成员函数,而在类中只用函数的原型作声明。

例15.3在类的外面定义成员函数。

#include<string. h>

#include<iostream.h> //声明一个类

class stud

{private:

int num ;

char name[10];

char sex ;

public:

stud(int n,char nam[],chars); //对构造函数的原型声明

~stud(); //对析构函数的原型声明

void display( ) ; //对成员函数 display的原型声明

};

stud: : stud (intn,char nam[].chars) //对构造函数的定义

{num=n;

strcpy(name,nam);

sex=s;} //对析构函数的定义

stud::~stud( )

{ } //对成员函数 display的定义

void stud:: display()

{cout<<"num:"<<num<<endl;

cout<<"name:"<<name<<endl;

cour<<"sex:"<<sex<<endl ;

}

void main( )

{

stud stud1(10010,"Wang-li”,'f'’),stud2(10011,"Zhang-fun",'m');

stud1,display( ): //输出学生1的数据

stud2.display(); //输出学生2的数据

}

请读者注意在类声明的外部定义函数,必须指定类名。函数首行的形式为

函数类型 类名::函数名(形参表列)

不能写成

void display( ) //未指定类名

如果这样写,编译系统会把它作为普通的函数处理,而不作为类中的成员函数。也不要写成:

stud::void display() //函数类型位置不对

stud::display()是一个整体,说明是stud 类中的 display 函数。不能把stud::和 display()分隔开来。

虽然函数在类的外部定义,但在调用成员函数时会根据类中函数的原型声明找到函数的定义(函数代码),从而执行该函数。

也可以将在类外部定义的函数声明为“内置函数”,这样在编译时就将函数代码代人到类中的函数调用处,以提高程序执行效率。只需在函数定义的首行最左端加上inline即可。如:

inline void stud:: display( )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光向日葵之沈阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值