第5章 类和对象1.docx

上传人:b****1 文档编号:12794688 上传时间:2023-04-22 格式:DOCX 页数:29 大小:26.38KB
下载 相关 举报
第5章 类和对象1.docx_第1页
第1页 / 共29页
第5章 类和对象1.docx_第2页
第2页 / 共29页
第5章 类和对象1.docx_第3页
第3页 / 共29页
第5章 类和对象1.docx_第4页
第4页 / 共29页
第5章 类和对象1.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

第5章 类和对象1.docx

《第5章 类和对象1.docx》由会员分享,可在线阅读,更多相关《第5章 类和对象1.docx(29页珍藏版)》请在冰豆网上搜索。

第5章 类和对象1.docx

第5章类和对象1

第5章类和对象

类是面向对象程序设计的核心,是实现信息封装的基础。

它实际上是一种新的数据类型,是对某一类对象的抽象,而对象是某一种类的实例。

对象和类是密切相关的,没有脱离对象的类,也没有不依赖于类的对象。

5.1类的定义

5.1.1什么是类

类是一种复杂数据类型,它是将不同类型的数据和与这些数据相关的操作封装在一起的集合体。

类是一种用户定义的类型。

有了这种类型使得应用中的实体在程序中可以直接作为一个标识符,对它进行引用和操作。

类是一种用户定义的类型。

有了这种类型使得应用中的实体在程序中可以直接作为一个标识符,对它进行引用和操作。

5.1.2类的定义格式

类的定义包括说明部分

实现部分

说明部分:

说明类中定义的成员。

(数据成员,成员函数)

实现部分:

定义成员函数。

类的定义格式:

class类名

{

public:

成员函数或数据成员的说明

protected:

数据成员或成员函数的说明

private:

数据成员或成员函数的说明

};

各个成员函数的实现

或者:

class类名

{

数据成员或成员函数的说明

public:

成员函数或数据成员的说明

protected:

数据成员或成员函数的说明

};

各个成员函数的实现

public

访问权限protected

Private

公有部分往往是一些操作(成员函数),它是用户的接口。

这部分成员用户在程序中可以使用。

私有部分通常是一些数据成员,是用来描述该类中的对象的属性的,用户无法访问它们,只有成员函数或友元函数才能访问它们。

它们是被用来隐藏的部分。

例如,定义一个日期类。

说明部分:

classTDate

{public:

voidSetDate(inty,intm,intd);

intIsLeapYear();

voidPrint();

private:

intyear,month,day;

};

实现部分:

voidTDate:

:

SetDate(inty,intm,intd)

{year=y;

month=m;

day=d;

}

intTDate:

:

IsLeapYear()

{return(year%4==0&&year%100!

=0)||

(year%400==0);

}

voidTDate:

:

Print()

{cout<

<

}

作用域运算符

类名:

函数名(参数表)

定义一个日期类还可以:

classTDate

{public:

voidSetDate(inty,intmintd)

{year=y;

month=m;

day=d;}

intIsLeapYear()

{return(year%4==0&&year%100!

=0)||

(year%400==0);}

voidPrint()

{cout<

<

private:

intyear,month,day;

};

这里实现部分被省略了。

成员函数的作用:

1.操作数据成员,包括访问和修改数据成员;

2.协同不同的对象操作,称为传递消息。

5.1.3定义类时注意事项

1.在类体内不允许对数据成员初始化。

classTDate

{public:

voidSetDate(inty,intmintd);

intIsLeapYear();

voidPrint();

private:

intyear(2004),month(9),day(29);

};

2.类中数据成员的类型是任意的。

整形、实型、字符型、数组、指针、引用和类类型等。

另一个类的对象,可以作该类的成员,但自身类的对象不行。

例1:

classstudent

{public:

……

private:

longcode;

charname[10];

TDatebirthday;//类类型成员

char*address;

charphone[20];

};

例2:

classN;//类说明

classM

{public:

……

private:

classNn;//n是N的对象

};

classN

{public:

voidf(Mn);//m是M类的对象

……

};

3.经常习惯地将类定义的说明部分或整个类的定义放到一个头文件中。

例如,定义一个点类,放在tpoint.h文件中。

classTpoint

{public:

voidSetPoint(intx,inty);

intXcoord(){returnX;}

intYcoord(){returnY;}

voidMove(intxoffset,intyoffset);

private:

intX,Y;

};

voidTpoint:

:

SetPoint(intx,inty)

{X=x;

Y=y;

}

voidTpoint:

:

Move(intxoffset,intyoffset)

{X+=xoffset;

Y+=yoffset;

}

5.2对象的定义

对象是类的实例。

对象是属于某个已知的类。

5.2.1对象的定义格式

定义格式:

类名对象名

例如:

TDatedate1,date2,*p,date[10];

Tpointp1,p2,*p,&d=p1;

5.2.2对象成员的表示方法

对象成员数据成员

成员函数

对象数据成员的表示:

对象名.成员名

例如:

date1.year,date1.month,date1.day

对象函数成员的表示:

对象名.成员名(参数表)

例如:

date1.SetDate(2004,9,28)

其中“.”是一个运算符。

指向对象的指针的成员:

对象指针名->成员名

例如:

Pdate->year

或者:

对象指针名->成员名(参数表)

例如:

Pdate->SetDate(2004,9,28)

下面两种表示相同:

对象指针名->成员名

*对象指针名.成员名

例如:

Pdate->year

*Pdate.year

 

例5.1分析输出结果。

tdate.h

classTDate

{public:

voidSetDate(inty,intm,intd)

{year=y;

month=m;

day=d;}

intIsLeapYear()

{return(year%4==0&&year%100!

=0)||

(year%400==0);}

voidPrint()

{cout<

<

private:

intyear,month,day;

};

#include

#include”tdate.h”

voidmain()

{TDatedate1,date2;

date1.SetDate(2004,10,8);

date2.SetDate(2005,10,8);

intleap1=date1.IsLeapYear();

cout<

intleap2=date2.IsLeapYear();

cout<

date1.Print();

date2.Print();

}

输出:

1

0

2004.10.8

2005.10.8

例5.2

#include

#include”tpoint.h”

voidmain()

{

Tpointp1,p2;

p1.SetPoint(3,5);

p2.SetPoint(8,10);

p1.Move(2,1);

p2.Move(1,-2);

cout<<”x1=”<

<

cout<<”x2=”<

<

}

结果:

x1=5,y1=6

x2=9,y2=8

例5.3访问对象的公有成员。

#include

classTclass

{public:

intx,y;

voidprint()

{cout<

};

voidmain()

{Tclasstest;

test.x=100;

test.y=200;

test.print();

}

输出:

100,200

例5.4用指针访问对象的公有成员。

#include

classTclass

{public:

intx,y;

voidprint()

{cout<

};

intadd(Tclass*ptf)

{return(ptf->x+ptf->y);}

voidmain()

{Tclasstest,*pt=new(Tclass);

pt->x=100;

pt->y=200;

pt->print();

test.x=150;

test.y=450;

test.print();

cout<<”x+y=”<

}

输出:

100,200

150,450

x+y=600

5.3对象的初始化

5.3.1构造函数和析构函数

构造函数的格式:

类名:

:

构造函数名(参数表)

{}

构造函数的功能:

是在创建对象时,使用给定的值为对象初始化。

析构造函数的格式:

类名:

~析构函数名()

{}

析构函数的功能:

是用来释放一个对象。

例5.5重新定义日期类

//tdate1.h

classTDate1

{public:

TDate1(inty,intm,intd);

~TDate1();

voidIsLeapYear();

voidPrint();

private:

intyear,month,day;

};

TDate1:

:

TDate1(inty,intm,intd)

{year=y;

month=m;

day=d;

cout<<”Constructorcalled.\n”;

}

TDate1:

:

~TDate1()

{cout<<”Destructorcalled.\n”;}

voidTDate1:

:

IsLeapYear()

{if(year%4==0&&year%100!

=0||

year%400==0)

cout<<”Isleapyear.\n”;

else

cout<<”Isnotleapyear.\n”;

}

voidTDate1:

:

Print()

{cout<

<

}

#include

#include”tdate1.h”

voidmain()

{TDate1today(2004,10,8),

tomorrow(2004.10,9);

cout<<”todayis“;

today.Print();

today.IsLeapYear();

cout<<”tomorrowis“;

tomorrow.Print();

}

输出:

ConstructorCalled.

ConstructorCalled.

todayis2004.10.8

Isleapyear.

tomorrowis2004.10.9

DestructorCalled.

DestructorCalled.

构造函数的特点:

1.构造函数是成员函数。

2.构造函数与类同名,不指定函数类型。

3.构造函数可以重载。

4.在创建对象时系统自动调用构造函数,在程序中不能直接调用构造函数。

析构函数的特点:

1.析构函数是成员函数。

2.析构造函数与类同名,并在前面加“~”字符,不指定函数类型,也没有参数。

3.一个类中只可以定义一个析构函数。

4.系统可以自动调用析构函数,在程序中也可以直接调用析构函数。

5.3.2缺省构造函数和缺省析构函数

缺省构造函数的格式:

类名:

缺省构造函数名()

{}

缺省构造函数在类中没有定义任何构造函数时系统自动生成;也可以用户自己定义。

例如:

Tpointp1,p2;

缺省构造函数对p1和p2进行初始化。

对象的所有数据成员都是不确定的。

缺省析构函数的格式:

类名:

~缺省析构函数名()

{}

缺省析构函数在类中没有定义析构函数时系统自动生成,是一个空函数。

例5.6重新定义日期类

//tdate2.h

classTDate2

{public:

TDate2();

~TDate2();

voidSetDate(inty,intm,intd);

voidIsLeapYear();

voidPrint();

private:

intyear,month,day;

};

TDate2:

:

TDate2()

{cout<<”Constructorcalled.\n”;}

TDate2:

:

~TDate2()

{cout<<”Destructorcalled.\n”;}

voidTDate2:

:

SetDate(inty,intm,intd)

{year=y;

month=m;

day=d;

}

voidTDate2:

:

IsLeapYear()

{if(year%4==0&&year%100!

=0||

year%400==0)

cout<<”Isleapyear.\n”;

else

cout<<”Isnotleapyear.\n”;

}

voidTDate2:

:

Print()

{cout<

<

}

#include

#include”tdate2.h”

voidmain()

{TDate2d;

cout<<”dis“;

d.Print();

d.SetDate(2004,10,8);

cout<<”dis“;

d.Print();

}

输出:

Constructorcalled.

dis-858993460,-858993460,-858993460

dis2004.10.8

Destructorcalled.

 

例5.7重新定义日期类

//tdate3.h

classTDate3

{public:

TDate3(int,int,int);

~TDate3();

voidSetDate(inty,intm,intd);

voidIsLeapYear();

voidPrint();

private:

intyear,month,day;

};

TDate3:

:

TDate3(inty,intm,intd)

{year=y;month=m;day=d;

cout<

Constructorcalled.\n”;}

TDate3:

:

~TDate3()

{cout<

<<”:

Destructorcalled.\n”;}

voidTDate3:

:

SetDate(inty,intm,intd)

{year=y;month=m;day=d;}

voidTDate3:

:

IsLeapYear()

{if(year%4==0&&year%100!

=0||

year%400==0)

cout<<”Isleapyear.\n”;

else

cout<<”Isnotleapyear.\n”;

}

voidTDate3:

:

Print()

{cout<

<

}

#include

#include”tdate3.h”

voidmain()

{TDate3d1(2000,5,1);

TDate3d2(2001,10,1);

d1.SetDate(1998,6,15);

d1.Print();

d1.IsLeapYear();

d1.SetDate(2000,9,23);

d1.Print();

d1.IsLeapYear();}

输出:

2000.5.1:

Constructorcalled.

2001.10.1:

Constructorcalled.

1998.6.15

Isnotleapyear.

2000.9.23

Isleapyear.

2001.10.1:

Destructorcalled.

2000.9.23:

Destructorcalled.

对象的构造和析构次序是相反的,先建立的对象后析构。

例5.8定义图书卡片类。

#include

#include

classCard

{public:

Card(char*t,char*name,intnum);

voidshow();

private:

chartitle[80];

charauthor[40];

intnumber;

};

Card:

:

Card(char*t,char*name,intnum)

{strcpy(title,t);

strcpy(author,name);

number=num;

}

voidCard:

:

show()

{cout<<”Title:

”<

cout<<”Author:

”<

cout<<”Number:

”<

}

voidmain()

{Cardbook1(“Basic”,”Tang”,10);

Cardbook2(“FORTRAN”,”Wang”,20);

book1.show();

book2.show();

}

输出:

Title:

Basic

Author:

Tang

Number:

10

Title:

FORTRAN

Author:

Wang

Number:

20

构造函数还有一种称为“初始式”的形式对数据成员置初值。

形式为:

构造函数名(参数表):

数据成员1(参数),

数据成员2(参数),…

{……}

例如:

TDate3:

:

TDate3(inty,intm,intd)

{year=y;month=m;day=d;

cout<<”:

Constructorcalled.\n”;}

可以:

TDate3:

:

TDate3(inty,intm,intd):

year(y),month(m),day(d)

{cout<<”:

Constructorcalled.\n”;}

例5.8对象成员初始化

#include

classA

{public:

A(intx):

a(x){}

inta;

};

classB

{public:

B(intx,inty):

aa(x),b(y){}

voidout()

{cout<<”aa=”<

<

private:

intb;

Aaa;

};

voidmain()

{BobjB(3,5);

objB.out();

}

输出:

aa=3

b=5

以上不能:

B(intx,inty)

{aa.a=x;b=y;}不能在构造函数中对类成员赋值

但可以:

B(intx,inty):

aa(x)

{b=y;}

5.3.3拷贝初始化构造函数

功能:

是用一个已知的对象来初始化一个被创建的同类的对象。

格式:

类名:

:

拷贝初始化构造函数名(const类名&引用名)

特点:

1.也是一种构造函数,函数名同类名。

2.只有一个参数,并且是对某个对象的引用。

3.如果类中没有说明拷贝初始化构造函数,则系统自动生成一个缺省拷贝初始化构造函数。

例5.9修改点类的定义。

//tpoint1.h

classTPoint

{public:

TPoint(intx,inty){X=x;Y=y;}

TPoint(TPoint&p);

~TPoint()

{cout<<”DestructorCalled.\n”;}

intXcoord(){returnX;}

intYcoord(){returnY;}

private:

intX,Y;

};

TPoint:

:

TPoint(TPoint&p)

{X=p.X;

Y=p.Y;

cout<<”Copy_initializationConstructorCalled.\n”;}

#include

#include”tpoint1.h”

voidmain()

{TPointP1(5,7);

TPointP2(P1);

cout<<”P2=”<

<

输出:

Copy_initializationConstructorCalled.

P2=5,7

DestructorCalled.

DestructorCalled.

例5.10拷贝初始化构造函数的其他用法。

#include

#include”tpoint1.h”

TPointf(TPointQ);

voidmain()

{TPoin

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 社交礼仪

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1