C++教程第07章_类与对象-3对象的初始化、构造

  • 格式:doc
  • 大小:78.00 KB
  • 文档页数:9

1 第7章 类与对象

7.1 类和对象

7.2成员函数的重载

7.3 对象的初始化、构造函数与析构函数

7.3.1 基本概念及定义

1. 对象的4种初始化方法

在使用对象中的成员数据之前,必须赋给它们确定的值;即在使用对象之前,首先要对对象中的成员数据进行初始化。

在定义类时不能对类中的成员数据直接初始化,但在创建对象时,可借助4种方法进行初始化。

1).初始化列表法。

这种方法只能对公有成员数据初始化,对私有和保护类的数据无能为力。

由于对象的封装性要求将类的成员数据都定义为私有的,因此这种方法不常用。

2).通过赋值语句来实现,即将一个已经初始化的对象赋给要初始化的对象。如前例。

3).在类中定义一个成员函数,该成员函数能够对对象的成员数据进行设置,如前例。

4).通过构造函数来进行初始化,它的特点是在创建对象的同时自动对对象中的成员数据进行初始化。

2 构造函数

C++规定与类同名的成员函数是构造函数,它是一个特殊的成员函数。

●构造函数的一般格式为:

::()

{ - - - }

例如:

class CSimpleString

{ char *string ;

int length ;

public:

CSimpleString (int) //

{ string = 0 ; length = a ;}

};

也可以:

class CSimpleString

{ char *string ;

int length ;

public:

CSimpleString (int); //声明构造函数

};

CSimpleString ::CSimpleString (int) //定义构造函数 2 { string = 0 ; length = a ;}

●构造函数具有如下特征:

1). 构造函数与类同名;

2).构造函数没有返回值,在声明和定义构造函数时,不能说明它的返回类型,即使void类型也不行。

3). 在创建对象时,首先调用该对象的构造函数,完成对该对象的初始化工作。对构造函数的调用是隐性的,由编译系统自动调用。

4). 在创建对象的引用时,由于它只是另一个对象的别名,此时不会调用构造函数。同样,在创建指针时,也不会调用构造函数,但用new运算符或其它方法对它初始化时,调用构造函数。

5). 如果在类中定义了构造函数,则自动调用该类中定义的构造函数,否则,为了逻辑上的完整性,编译系统会自动产生一个默认的构造函数,其格式为:

::(){ }

此构造函数,并没有对对象种的成员数据做任何的初始化工作。调用默认的构造函数后,对象中的数据是不确定的,还必须采用其它方法对对象中的成员数据进行初始化。

6). 构造函数的重载与普通函数一样。一个类可以有多个构造函数,这样使类具有更大的灵活性,可以根据不同的要求进行不同的初始化。

● 构造函数的调用

1)在创建对象时可以向构造函数传递实参,一般格式:

〈〈 (实参表) 〉〉;

其中为向构造函数传递的参数。该实参表必须与某个构造函数的参数的类型和个数一致。

2). 如果在创建对象时没有向构造函数向构造函数传递实参,则对象后面不能加括号。

2 析构函数

撤消对象时,会自动调用析构函数,析构函数常承担撤消对象后的善后处理工作。它也是一个特殊的成员函数。

● 析构函数的格式为:

::~ ( )

{ - - - }

● 特征:

1)函数名为类名前加字符“~” 。

2)没有参数,也没有返回类型。因此它不能重载。

3)当撤消对象时自动调用析构函数。

4)当没有定义析构函数时,系统会自动产生析构函数,该函数为空函数,并不做任何工作。

●撤消对象的两种方式:

1)自动撤消

对于局部自动类型的对象,当超出其作用域,对象将自动撤消;

对于全局和静态类型的对象,当程序终止时自动撤消对象;

对临时对象,在该对象参与运算之后立即撤消;

析构函数的调用顺序正好与构造函数相反。 3 2)主动撤消

即当用new运算符为对象指针动态分配存储空间,而用delete释放该存储空间时将撤消该对象。

7.3.2 构造与析构函数使用示例

1. 构造函数的初始化作用

#include

class CPoint

{ int x , y ;

public:

CPoint (int vx , int vy );

void offset(int ax ,int ay);

void Print()

{ cout<<"横坐标为:"<

cout<<"纵坐标为:"<

}

};

CPoint ::CPoint(int vx ,int vy)

{ x=vx ;

y=vy ;

cout<<"调用构造函数CPoint(int , int)!\n" ;

}

void CPoint ::offset(int ax , int ay)

{ x=x+ax ;

y=y+ay ;

}

void main()

{ CPoint pt1(20 ,30) ; //A

pt1.Print() ;

pt1.offset(10 ,10) ;

pt1.Print() ;

}

运行结果:

调用构造函数CPoint(int , int)!

横坐标为:20

纵坐标为:30

横坐标为:30

纵坐标为:40

2. 构造函数的重载

构造函数的重载与普通函数一样。一个类可以有多个构造函数,这样使类具有更大的灵活性,可以根据不同的要求进行不同的初始化。

#include 4 class Cylinder

{public:

Cylinder( ){ }

Cylinder(double r , double h);

void setcylinder(double r ,double h);

double gettradius( ){return radius;}

double getheight( ){return height;}

double volume( );

double surface_area();

private:

double radius;

double height ;

};

const double PI=3.1415926;

Cylinder ::Cylinder(double r , double h)

{ radius=r ; height=h ;}

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 Cylinder(7.0 , 12.0) , Cylinder2 ; //A

Cylinder2.setcylinder(12.3 ,18.7) ;

cout<<”the radius of cylinder1 is :\t”<< cylinder1.getradius( )<

cout<<”the height of cylinder1 is :\t”<< cylinder1.getheight( )<

cout<<”the volume of cylinder1 is :\t”<< cylinder1.volume( )<

cout<<”the surface area of cylinder1 is :\t”<< cylinder1.surface_area()<

cout<<”the radius of cylinder2 is :\t”<< cylinder2.getradius( )<

cout<<”the height of cylinder2 is :\t”<< cylinder2.getheight( )<

cout<<”the volume of cylinder2 is :\t”<< cylinder2.volume( )<

cout<<”the surface area of cylinder2 is :\t”<< cylinder2.surface_area()<

执行结果:

the radius of cylinder1 is : 7.0

the height of cylinder1 is : 12.0

the volume of cylinder1 is : 1847.26

the surface area of cylinder1 is : 835.664