面向对象程序设计课件2017春-第3章类_第1页
面向对象程序设计课件2017春-第3章类_第2页
面向对象程序设计课件2017春-第3章类_第3页
面向对象程序设计课件2017春-第3章类_第4页
面向对象程序设计课件2017春-第3章类_第5页
免费预览已结束,剩余52页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章类(Class)主讲:严冬梅面

象程序设计(C++)Oriented

Object

Programming

(C++)第3章类3.1

从结构到类3.2

类的定义3.3

对象3.4

成员函数3.5

再论程序结构3.6

string类3.7

局部类和嵌套类*3.1

从结构到类struct

Date

{intyear;intmonth;int

day;};所有成员外部可见Dated;

d.year=2000;struct

Point{double

x,y;};struct

Circle{Point

center;double

radius;};3.1.1

定义结构结构类型是一种复合类型,属性的类型可以不同。数据类型名称一般用大写字母开头(与类相同)成员可以嵌套3.1

从结构到类3.1.3

类与结构的区别本质区别类,不仅描述数据,还描述行为结构,单纯堆积数据空间构造的类型数据(属性、成员)的差别类定义中默认情况下的成员是private的而结构定义中默认情况下的成员是public的。3.1

从结构到类3.1.2

类与结构的区别struct

Savings

{unsigned

accountNumber;float

balance;};void

fn(){Savings

a,b;a.accountNumber=1;

√b.accountNumber=2

√}3.1

从结构到类class

Savings

{public:unsigned

deposit(unsigned

account){

balance

+=

amount;

return

balance;

}private:unsigned

accountNumber;float

balance;}void

fn(){Savings

a,

b;a.balance

=

100.5;

×b.balance

=

200.5;

×a.deposit(100);}3.2

类的定义class

类名{<

<private:>成员表1;><protected:成员表2;><public:成员表3;>};3.2.1

类的一般结构其中“class类名”称为类头(classhead)。花括号中的部分称为类体(classbody),类体中定义了类成员表(class

membelist),包存取控制权限public成员多为函数,private成员多为数据。3.2

类的定义public在public部分的成员描述了对象外部可见的特征,这些成员函数,所 的成数据成员是不恰当的。成员被称为公有成员。这部分应该只员函数构成对象的操作接口,而用于private在private部分

的成员描述了对象

可见的特征,这是外部不可见的特征,因而提供了信息隐藏。这部分主要用来数据成员,以给出数据结构的实现。但是,在这部分也可以成员函数,这些函数是外部不可

的,它们用于辅助实现其它函数。在这部分

的成员称为私有成员。protected。用于

保护的成员,这部分的作用与类继承有关,以后当没有类继承的时候,保护成员与私有成员的性质相同,外部均不能

。3.2

类的定义3.2.2

注意:在类定义中不能对数据成员进行初始化;类中数据成员的类型可以是任意的,甚至可以是另一个类的对象,但自身类的对象是不可以的,而自身类的指针或又是可以的;一般地,在类体内先说明公有成员,它们是用户所关心的,后说明私有成员,它们是用户不感的。在说明数据成员时,一般按数据成员的类型大小,由小至大说明,这样可提高时空利用率;类的规范说明部分通常存放在一个单独的文件中,这个文件被成为头文件,后缀为.h,名字通常为类的英文单词。3.2

类的定义早期

上,以字母“T”作为一个类名的开始,以表示它代表一个类或类型,标识各种成员名字的标识符一般使用大写字母开始。class

TPoint

{public:TPoint(int

x,

int

y);int

XGoord();intYGoord();void

Move(int

xOffset,

int

yOffset);private:int

X,Y;};3.2

类的定义面

象的特征抽象(

ion)封装(Encapsulation)继承(Inheritance)多态(Polymorphism)3.2

类的定义类的表示(UML

建模语言)StartUML、Rational

Rose、VisioCircle-radius:double+Circle()+Circle(r:double)+getRadius():double+setRadius(r:double):void类名属性构造函数与行为3.3

对象3.3.1

对象的定义和格式:<

类型><class>类名对象名;Date

d;说明:对象就是变量,其作用域由定义的位置决定,生命期由

的位置决定。对象是类的实例,是在程序运行期间真正进行处理的数据。定义类时并不分配内存,只是说明了对象的分配模式,定义对象时才分配内存。dyearmonthday3.3

对象3.3.2对象按成员定义的顺序在连续的内存单元中class

Date

{public:……private:int

year;int

month;int

day;};Date

d1;Date

d1

=new

Date;4字节4字节4字节12字节&d==&d.year3.3

对象3.3.3

类的组合一个类的数据成员是另一个类的对象class

Student

{public:……private:int

num;char

name[10];Date

birthDate;};Studenta;anumnameyearmonthday4字节10字节4字节4字节4字节26字节&a==&a.num3.3

对象3.3.4

对象数组Student

stu[40];stu=&stu[0]=&stu[0].numstustu[0].numstu[0].namestu[0].birthDate.yearstu[0].birthDate.monthstu[0].birthDate.daystu[1]……stu[39]26字节26字节26字节26*40字节3.3

对象3.3.5

对象指针Student

*pStu

=

&s;pStu

=

stu;

pStu++;可以通过指针

成员pStu->num

或(*pStu).num3.3.6

对象Student

&rStu

=

s;rStu.num

s.num3.4

成员函数3.4.1

成员函数的定义与说明成员函数是对象的行为,需要在类定义中进行描述。在类中定义成员函数如果在类定义中进行成员函数的定义,则该成员函数被系统默认为内联函数,会编译多次。3.4

成员函数【例3.1】在类中定义成员函数class

Date{public:void

Set(int

y,

int

m,

int

d){

year=y;

month=m;

day=d;

}int

IsLeapYear(){return

(year%4==0&&year%100!=0)||(year%400==0);}void

Print(){

cout

<<month

<<"/"

<<day

<<"/"

<<year

<<endl;

}private:int

year;int

month;int

day;};3.4

成员函数在类定义外定义成员函数

将类定义和其成员函数的定义分开,此时函数名为类名::成员函数名::称为作用域区分符,指明一个函数属于哪个类类成员函数的定义格式<返回类型><类名>::<成员函数名>(<参数说明>){}3.4

成员函数【例3.2】在类定义外定义成员函数class

Date{public:void

Set(int

y,

int

m,

int

d);int

IsLeapYear();void

Print();private:

int

year;int

month;int

day;};void

Date::Set(int

y,

int

m,

int

d){

year=y;

month=m;

day=d;

}int

Date::IsLeapYear(){return

(year%4==0&&year%100!=0)||(year%400==0);

}void

Date::Print(){

cout

<<month

<<"/"

<<day

<<"/"

<<year

<<endl;

}3.4

成员函数成员函数的重载一个类中的成员函数可以重载class

Date{public:voidSet(inty,intm,

int

d);voidSet(inty,intm);voidSet(inty);voidSet();……};类名是成员函数名的一部分,所以一个类的成员函数与另一个类的成员函数即使重名,也不能认为是重载。3.4

成员函数成员函数可以默认参数需要注意的是:必须在类定义中默认class

Date{public:void

Set(inty=2000,

int

m=1,

int

d=1);……};void

Date::Set(int

y,

int

m,

int

d){……}3.4

成员函数3.4.2

调用成员函数调用一个成员函数必须指定对象和成员名。void

func(){ Date

oneday;oneday.Set(2017,

3,

27);oneday.Print();}用指针调用成员函数Date

*pDate,

d;pDate=&d;pDate->Set(2017,

3,

27);3.4

成员函数用

传递来

成员函数与使用对象自身的情况一样简单void

someFunc(Date

&refs){refs.Print();

//refs是s对象的别名if(refs.IsLeapYear())cout

<<"oh

no\n";elsecout

<<"right\n";}int

main(){ Date

s;s.Set(2017,

3,

27);someFunc(s);

//对象的地址传给return

0;}3.4

成员函数3.4.2

在成员函数中

成员程序编译后,每个对象都有自己的空间存放其数据成员,而成员函数只有一份,成员函数是如何区分此对象与彼对象呢?voidDate::Set(int

y,

int

m,

int

d){ year=y;

month=m;

day=d;

}voidDate::Print(){ cout<<month<<"/"<<day<<"/"<<year<<endl;

}intmain(){ Date

d1,

d2;d1.Set(2016,

12,

25);

d1.Print();d2.Set(2017,

3,

27);

d2.Print();return

0;}3.4

成员函数this指针在普通的成员函数中,有一个隐含指针——this指针。一个类中所有成员函数共享同一代码段,在调用成员

函数时,除了传递参数外,还传递对象的地址给隐含

的this指针,成员函数中

该类成员无需指明是哪个对象。编译器可以根据this指针来确定应该

哪个对象的数据成员。month=12;<=>this->month

=12;this指针是一个局部变量一个类的对象所占内存空间由它的数据成员所占的空间总和所决定,与其成员函数无关。3.4

成员函数3.4.4

获取器与设置器getter(

器accessor)TypeOfProperty

getPropertyName();setter(更改器mutator)voidsetPropertyName(TypeOfProperty);布尔型get函数bool

isPropertyName();3.4

成员函数3.4.4

保护成员设置保护屏障,由OO程序的目标有关:相对于外部函数(普通函数、其它类的成员函数)而言,保护类的使类对它

实现的数据不被肆意

。负责。限制类与外部世界的接口。减少类与其它代码的关联程度。保护成员的实现设成proctected或private或默认用不同数目的参数3.4

成员函数3.4.5

类的

实现编制应用程序时,使用某个类,只需了解其公共成员。【例3.3】类的封装class

Point{

public:void

Set(double

ix,

double

iy)

{

x=ix;

y=iy;

}double

xOffset()

{

return

x;

}double

yOffset()

{return

y;

}double

angle()

{return

(180/3.14159)*atan2(y,x);}double

radius()

{

return

sqrt(x*x+y*y);

}protected:double

x;//x轴分量double

y;//y轴分量};intmain(){ Point

p;

double

x,

y;while

(1){//输入x和y轴分量,直到x分量值小于0cout<<"Input

x

and

y:";cin

>>x>>y;if

(x<0

||

y<0)

break;p.Set(x,y);cout

<<"angle="

<<p.angle()<<",radius="<<p.radius()<<",x

offset="<<p.xOffset()<<",y

offset="

<<p.yOffset()

<<endl;}//whilereturn

0;}3.4

成员函数3.5

再论程序结构3.5.1

类的作用域类作用域是指类定义和相应的成员函数定义范围。对类作用域外的一个类的数据成员和成员函数的受到程序员的限制。class

Date{…………};void

Date::Set(int

y,

int

m,

int

d){

year=y;

month=m;

day=d;}…………void

Date::Print(){

cout

<<month

<<"/"

<<day

<<"/"

<<year

<<endl;

}int

main()

{

…………

}void

func()

{

…………

}3.5

再论程序结构3.5.2

可见性一个非类型名隐藏了一个类型名,类型名通过加前缀

。如果一个类型名隐藏了一个非类型名,则用一般作用域规则。一般作用域规则:

局部类的作用域在定义该类的模块中,其成员函数必须在类定义

定义。名空间—某名字在其中必须唯一的作用域。一个名字不能同时指两种类型。非类型名不能重名。类型与非类型不在同一名空间,同时出现,类型名前要加前缀。3.5

再论程序结构classSample{……};voidfunc(int

Sample){

class

Sample

a;Sample++;……}int

s=0;void

func(){

class

s

{

……};s

a;::s=3;……}3.5

再论程序结构3.5.3

类的封装

数据与算法(操作)结合,构成一个不可分割的整体。

在这个整体中一些成员是保护的,它们

被有效地

,以防外界的干扰和误操作。另一些成员是公共的,它们作为接口提供给外界使用。3.5

再论程序结构class程序结构date.h,date.cpp,*.cppclass

Date{public:void

Set(int,int,int);intIsLeapYear();

void

Print();private:

int

month;int

day;int

year;};#include

“date.h”#include

<iostream>using

namespace

std;void

Date::Set(int

m,int

d,int

y){

month=m;

day=d;

year=y;

}int

Date::IsLeapYear()

{return

(year%4==0&&year%100!=0)||(year%400==0);}void

Date::Print()

{cout

<<month

<<"/"

<<day<<"/"

<<year

<<endl;}3.5

再论程序结构3.5.4

类库的构成类定义(头文件)成员函数(编译实现的代码)定义。3.5.5

C++的程序结构C++程序main.cppclass.cpp

sfunction.cpp

s3.5

再论程序结构一个C++的

系统的物理组织:实现文件A主文件头文件A头文件B实现文件B头文件C实现文件C3.5

再论程序结构main.cpp#include

<标准类库头文件>

s#include

<标准函数头文件>

s#include

“自定义类库头文件”

s#include

“自定义函数头文件”

s函数原型

s全局数据定义

sint

main(){

……

}函数定义s3.5

再论程序结构class.cpp#include

<标准函数头文件>

s#include “自定义类库头文件”

s成员函数定义

s#include

<标准类库头文件>

s3.5

再论程序结构function.cpp#include

<标准类库头文件>

s#include

<标准函数头文件>

s#include

“自定义类库头文件”

s#include

“自定义函数头文件”

s全局数据定义

s函数定义s3.5

再论程序结构//Circle.hclass

Circle

{public:Circle();Circle(double);double

getArea();double

getRadius();void

setRadius(double);private:double

radius_;};【例3.4】多文件结构3.5

再论程序结构//Circle.cpp#include

"Circle.h"Circle::Circle(){

radius_

=

1;

}Circle::Circle(double

newRadius){

radius_

=

newRadius;

}double

Circle::getArea(){return

radius_

*

radius_

*

3.14159;

}double

Circle::getRadius(){

return

radius_;

}void

Circle::setRadius(double

newRadius){

radius_

=

(newRadius

>=

0)?newRadius:0;

}3.5

再论程序结构#include

<iostream>

//

main.cpp#include

"Circle.h"using

namespace

std;double

sum(Circle

circleArray[],

int

size){

double

sum

=

0;for

(int

i

=

0;

i

<

size;

i++)sum

+=

circleArray[i].getArea();return

sum;}void

printCircleArray(Circle

circleArray[],

int

size){

cout

<<

"Radius\t"

<<

"Area"

<<

endl;for

(int

i

=

0;

i

<

size;

i++)cout<<circleArray[i].getRadius()<<"\t"<<circleArray[i].getArea()<<endl;cout<<"-----------------------------------------“<<endl;cout

<<

"The

total

areas

of

circles

is

\t"<< sum(circleArray,

size)

<<

endl;}3.5

再论程序结构//接前页int

main(){const

int

SIZE

=

10;//

Create

a

Circle

object

withCircle

circleArray[SIZE];for

(int

i

=

0;

i

<

SIZE;

i++)circleArray[i].setRadius(i

+}printCircleArray(circleArray,

SIZE);return

0;}3.6

string类C++中通常使用string类处理字符串string类中的成员函数构造追加赋值位置与清除长度与容量比较子串搜索运算符3.6

string类注意:字符串处理过程中的index指的是“位序”e

to

Cand

C++!‘W’的位序为1,‘W’的下标为0‘d’的位序为16,‘d’的下标为15pare(s2);pare(1,

10,

s2);3.6

string类【例3.5】使用string类成员函数1#include

<iostream>#include

<string>using

namespace

std;int

main(){

string

s1(" o");

string

s2(s1);cout<<

"s1:"

<<

s1

<<

endl;

cout<<

"s2:"

<<

s2

<<

endl;s1.append("

world");s1.append(s2);cout<<"s1:"<<s1<<endl;cout<<"strlen(s1):"<<s1.size()<<endl;s1.assign("abcdefg",

2,

3);cout<<

"s1:"

<<

s1

<<

endl;cout

<< pare("dbb")

<<

endl;return

0;}3.6

string类#include<iostream>W#include<string>Comeusing

namespace

std;Comint

main()3{

strings1("

e");cout<<s1.substr(0,

1)

<<

endl;

//W-1cout<<s1.substr(3)

<<endl;e4cout<<

s1.substr(3,

3)

<<

endl;9}string

s2(" e

toC++");cout

<<

s2.find("Co")

<<

endl;

//3cout

<<

s2.find("Co",

6)

<<

endl;

//42959672995int

i

=

s2.find("Co",

6);cout

<<

i

<<

endl;

//-1cout

<<

s2.find('o')

<<

endl;

//4cout

<<

s2.find('o',

6)

<<

endl;

//9return

0;【例3.6】使用string类成员函数23.6

string类【例3.7】使用string类成员函数3#include

<iostream>#include

<string>using

namespace

std;int

main(){

strings1(" e

toHTML");s1.insert(11,

"C++

and

");cout

<<

s1

<<

endl;string

s2("AA");s2.insert(1,

4,

'B');cout

<<

s2

<<endl;string

s3(" e

toHTML");s3.replace(11,

4,

"C++");cout

<<

s3

<<

endl;return

0;}3.6

string类string类运算符运算符功能[]用数组下标运算符 字符串中的字符=将一个字符串的内容

到另一个字符串+连接两个字符串+=将一个字符串追加到另一个字符串<<将一个字符串 一个流>>从一个流提取一个字符串,分界符为空格或者空结束符==,

!=,

<,<=,

>,

>=用于字符串比较3.6

string类#include

<iostream>#include

<string>using

namespace

std;int

main(){

string

s1

="AB

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论