3C第三章讲解.docx

上传人:b****6 文档编号:3646310 上传时间:2022-11-24 格式:DOCX 页数:38 大小:25.75KB
下载 相关 举报
3C第三章讲解.docx_第1页
第1页 / 共38页
3C第三章讲解.docx_第2页
第2页 / 共38页
3C第三章讲解.docx_第3页
第3页 / 共38页
3C第三章讲解.docx_第4页
第4页 / 共38页
3C第三章讲解.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

3C第三章讲解.docx

《3C第三章讲解.docx》由会员分享,可在线阅读,更多相关《3C第三章讲解.docx(38页珍藏版)》请在冰豆网上搜索。

3C第三章讲解.docx

3C第三章讲解

#include

usingnamespacestd;

classPoint

{

private:

doublex;

doubley;

public:

doublegetx()

{

returnx;

}

doublegety()

{

returny;

}

voidsetx(doublex);

voidsety(doubley);

};

voidPoint:

:

setx(doublexx)

{

x=xx;

}

voidPoint:

:

sety(doubleyy)

{

y=yy;

}

intmain()

{

doublea;

a=1;

Pointp1,p2,p3;

Pointp[10];

p1.setx(0);

p1.sety(0);

cout<

return0;

}

 

#include

#include

usingnamespacestd;

classStudent

{

private:

intage;

char*name;

public:

Student(inta,char*n);

Student();

voidshow()

{

cout<

}

};

Student:

:

Student(inta,char*n)

{

age=a;

name=newchar[strlen(n)+1];

strcpy(name,n);

}

Student:

:

Student()

{

age=18;

name=newchar[50];

strcpy(name,"zhang");

}

intmain()

{

Students1,s2(24,"ling");

s1.show();

s2.show();

}

#include

#include

usingnamespacestd;

classPoint

{

private:

doublex;

doubley;

public:

Point(intxx,intyy)

{

x=xx;

y=yy;

}

Point(intxx=0)

{

x=y=xx;

}

voidshow()

{

cout<

}

};

intmain()

{

Pointp1(0,1),p2;

p1.show();

p2.show();

return0;

}

第三章类与对象

类是实现数据封装(类能够把数据和算法组合在一起,构成一个不可分割的整体;类具有信息隐藏的能力,能够有效地把内部数据隐藏起来,使外部函数只有通过类的公有成员才能访问内部数据)和信息隐藏(使结构中的数据和对数据进行操作的细节对外不可见)的工具,有别于普通数据类型的自定义数据类型,同时包括数据和函数的定义并将它们组合成一个整体。

对象是由类定义出来的变量,必须用成员访问限定符“.”作为对象名和对象成员之间的间隔符。

同一个类的不同对象之间(两个对象之间类型必须相同),以及同一个类的对象指针之间可以相互赋值(值的拷贝,赋值完成后对象之间互不相关)。

如果定义了对象指针,要用“->”作为指针对象和对象成员之间的间隔符。

对象的生存期是指对象从它被创建开始到被销毁前在内存中存在的时间,分为静态生存期(全局变量和静态变量具有与程序运行期相同的生存期)和动态生存期(局部对象从它的定义位置开始,遇到离它最近的“}”就结束了)。

类的用法(关键字class):

classclass_name//类名,常用首字符大写的标识符

{

private:

//可以省略

data_member;//数据成员

functin_name;//成员函数

public:

data_member;

functin_name;

protected:

data_member;

functin_name;

};//分号不可少

对象的定义:

类名对象1,对象2;

对象的引用:

对象名.数据成员名

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

对象的赋值:

对象名1=对象名2;

类构成了一种特殊的作用域,称为类域(指类定义时的一对花括号所括起来的范围)。

类域范围内的成员可以相互访问,不受成员访问控制权限的限定,类外的函数则只能访问的公有成员。

类的数据成员与某个成员函数内定义的变量同名,可以用类名:

:

数据成员名的方式访问数据成员。

形式:

classX

{//类域开始

……

}//类域结束

例Clock类

#include

#include

usingnamespacestd;

classClock

{

private:

inth;

intm;

ints;

public:

voidseth(inthh)

{

h=hh;

}

voidsetm(intmm)

{

m=mm;

}

voidsets(intss)

{

s=ss;

}

voiddisptime();

};

voidClock:

:

disptime()

{

cout<<"Nowis"<

"<

"<

}

intmain()

{

Clock*pa,*pb,aClock,bClock;

aClock.seth(16);//在类域外访问类的公有成员

aClock.setm(12);

aClock.sets(27);

bClock=aClock;

pa=newClock;

pa->seth(10);

pa->setm(23);

pa->sets(34);

pb=pa;

pa->disptime();

pb->disptime();

aClock.disptime();

bClock.disptime();

}

例对象的生存期

#include

usingnamespacestd;

classX

{

public:

X(intii=1)

{

i=ii;

cout<<"X("<

}

~X()

{

cout<<"X("<

}

private:

inti;

};

classZ

{

public:

Z():

x3(3),x2

(2)

{

cout<<"Zcreated"<

}

~Z()

{

cout<<"Zdestroyed"<

}

private:

Xx1,x2,x3;

};

Xa(200);//a的生存期开始

intmain()

{

Zz;//z的生存期开始,且其成员对象x1\x2\x3的生存期开始,且先于z

{

Xc(100);//c的生存期开始

staticXb(50);//b的生存期开始

}//c的生存期结束

}//z\x3\x2\x1\b的生存期依次结束

//main函数结束后,a的生存期才结束

一、结构的扩展

对比结构,添加了成员函数和访问权限。

访问权限限定符没有先后次序之分,出现次数没有限制,有效范围是从其开始直到下一个权限设置。

数据成员可以是任何的数据类型,但不能是自身类的对象,不能指定为auto、register、extern存储类型在声明类时,不能为数据成员赋初值。

访问权限限定符(用于指定数据成员和成员函数的访问权限):

(1)public:

被设置为public权限的成员称为类的公有成员,可以被任何函数访问。

Public区域中的成员称为类的接口;

(2)private:

被设置为private权限的成员称为类的私有成员,只能被结构内部的成员访问;

(3)protected:

与继承有关。

例包含数据和数据操作函数的复数结构

#include

usingnamespacestd;

classComplex

{

private:

doubler;

doublei;

public:

voidinit(doublerr,doubleii)

{

r=rr;

i=ii;

}

doublereal()

{

returnr;

}

doubleimage()

{

returni;

}

};

intmain()

{

Complexa;

a.init(2,3);

cout<

return0;

}

二、成员函数

两种定义方式:

(1)在声明类时就给出成员函数的定义,这种方式定义的成员函数若符合内联函数的条件,会被处理为内联函数。

例Date类的定义

classDate

{

private:

intday,month,year;

public:

voidinit(intd,intm,inty)

{

day=d;

month=m;

year=y;

}

intgetday()

{

returnday;

}

};

(2)在声明类时,只声明成员函数的原型,然后在类的外部定义成员函数。

若在类外成员函数的定义前加上关键字inline,该成员函数就被定义为内联函数。

用法:

r_typeclass_name:

:

f_Name(T1p1,T2p2,…);

注:

r_type是成员函数的返回类型,:

是域限定符,f_Name是成员函数名,T1、T2是参数类型,p1、p2是形式参数,在函数原型中形参名可以省略。

例Date类的定义

classData

{

private:

intday,month,year;

public:

voidinit(int,int,int);

intgetday();

};

inlinevoidDate:

:

init(intd,intm,inty)

{

day=d;

month=m;

year=y;

}

intDate:

:

getday()

{

returnday;

}

为了禁止成员函数(只有类的成员函数)修改数据成员的值,可以将它设置成常量成员函数。

用法:

classx

{

……

Tf(T1,T2,…)const;

……

};

T是函数返回类型,f是函数名,T1、T2是各参数的类型。

将成员函数设置成const类型后,该成员函数不会修改任何数据成员的值。

三、构造函数

构造函数是与类同名的特殊成员函数,在对象被定义之后的第一时间被调用,主要用来初始化对象的数据成员。

构造函数通常定义为公有成员,与类同名,没有返回类型,可以被重载,由系统自动调用,不允许在程序中显式调用。

定义数组对象时,必须有不需要参数的构造函数。

可以在类的内部定义构造函数,也可以在类中声明构造函数,任何在类外进行定义。

内部定义用法:

classX//类名

{

……

X(…)//构造函数

{

……

}

……

};

外部定义用法:

X:

:

X(…);

{

……

};

例Desk类的构造函数

#include

usingnamespacestd;

classDesk

{

public:

Desk(int,int,int,int);//构造函数声明

voidsetWeight(intw)

{

weight=w;

}

private:

intweight,length,width,high;

};

Desk:

:

Desk(intww,intl,intw,inth)//构造函数定义

{

weight=ww;

high=h;

width=w;

length=l;

cout<<"callconstructor!

"<

}

intmain()

{

Deskd1(2,3,4,5);

Desk*pd;

pd=newDesk(1,1,1,1);

}

(1)无参构造函数

a.默认构造函数

每个类必须有构造函数,如果一个类没有定义任何构造函数,在需要的时候,编译器将为它生成一个默认构造函数,负责对象的创建和初始化(全局对象或静态对象,所有数据成员初始化为0,局部对象不进行初始值设置)。

默认构造函数类似于:

classX

{

X(){}

……

};

b.缺省参数构造函数

有些构造函数的参数在多数情况下都比较固定,只是有时会发生变化,可以将它们的参数定义为缺省参数,即为参数提供默认值。

例定义Point类的无参数构造函数和缺省构造函数(如果显式定义了无参数的构造函数,又定义了全部参数都有默认值的构造函数,容易在定义对象时产生二义性)

#include

usingnamespacestd;

classpoint

{

private:

intx,y;

public:

point(inta,intb)

{

x=a;

y=b;

}

intgetx()

{

returnx;

}

intgety()

{

returny;

}

/*

point()

{

x=0;

y=0;

}//显式定义无参构造函数

*/

point(inta=0,intb=0)//缺省参数构造函数

{

x=a;

y=b;

}

};

pointp0;//调用构造函数point(),a、b默认为0

pointp1(1,1);//调用构造函数point(inta,intb)

intmain()

{

staticpointp2;//调用构造函数point(),a、b默认为0

pointp3;//调用构造函数point(),a、b默认为0

pointa[10];//调用构造函数point(),a、b默认为0

point*p4;//不调用任何构造函数

p4=newpoint;//调用构造函数point(),a、b默认为0

cout<<"p0:

"<

cout<<"p1:

"<

cout<<"p2:

"<

cout<<"p3:

"<

cout<<"p4:

"<getx()<<","<gety()<

cout<<"a[0]:

"<

}

c.重载构造函数

重载的构造函数必须有不同的函数原型

例重载Tdate的构造函数

#include

usingnamespacestd;

classTdate

{

public:

Tdate();

Tdate(intd);

Tdate(intm,intd);

Tdate(intm,intd,inty);

protected:

intmonth,day,year;

};

Tdate:

:

Tdate()

{

month=4;

day=1;

year=1995;

cout<

}

Tdate:

:

Tdate(intd)

{

month=4;

day=d;

year=1995;

cout<

}

Tdate:

:

Tdate(intm,intd)

{

month=m;

day=d;

year=1995;

cout<

}

Tdate:

:

Tdate(intm,intd,inty)

{

month=m;

day=d;

year=y;

cout<

}

intmain()

{

Tdateoneday;

Tdateaday();//函数返回一个Tdate类型的对象

Tdatebday1(10);

Tdatebday2=10;//等价于Tdatebday2(10);

Tdatecday(2,12);

Tdatedday(1,2,1998);

}

d.拷贝构造函数

如果在一个类中要用已存在的对象初始化另一个对象,如果没有定义类的拷贝构造函数,在需要时,编译器将产生一个具有最小功能的默认拷贝构造函数。

默认拷贝构造函数以成员按位复制(把一个对象各数据成员的值原样复制到目标对象中)的方式实现成员的复制。

拷贝构造函数与类同名,没有返回类型,可以重载。

当一个类存在指针类型的数据成员时,默认拷贝构造函数常会产生指针悬挂问题,故需要为它提供显式的拷贝构造函数。

默认拷贝构造函数的形式类似于:

X:

:

X(constX&){}//参数常是const类型的本类对象的引用

调用情况:

1.初始化新对象

2.用对象作为函数的参数

3.用返回值作为函数的参数

classX();

Xobj1;

Xobj2=obj1;//情况1,同Xobj2(obj1);

f(Xo);//情况2

Xf()

{

Xt;

……

returnt;//情况3

}

例为Person类定义拷贝构造函数

#include

#include

usingnamespacestd;

classPerson

{

private:

char*name;

intage;

public:

Person(char*Name,intAge);

~Person();

voidsetAge(intx)

{

age=x;

}

voidprint();

Person(constPerson&p);//拷贝构造函数,深拷贝

};

Person:

:

Person(char*Name,intAge)

{

name=newchar[strlen(Name)+1];

strcpy(name,Name);

age=Age;

cout<<"constructor"<

}

Person:

:

~Person()

{

cout<<"destructor"<

deletename;

}

voidPerson:

:

print()

{

cout<

"<

}

Person:

:

Person(constPerson&p)

{

name=newchar[strlen(p.name)+1];

strcpy(name,p.name);

age=p.age;

cout<<"Copyconstructor"<

}

intmain()

{

Personp1("zhang",21);

Personp2=p1;

p1.setAge

(1);

p2.setAge

(2);

p1.print();

p2.print();

}

e.初始化列表

构造函数可以采用成员初始化列表的方式对数据成员进行初始化。

介于构造函数参数表后面的“:

”与函数体{…}之间的内容就是成员初始化列表,将括号中的初始值赋给该括号前的成员。

常量成员、引用成员、类对象成员以及派生类构造函数对基类构造函数的调用等必须用初始化列表进行初始化,列表中的成员初始化次序与它们在类中的声明相同,构造函数初始化列表先于构造函数体中的语句执行。

成员初始化列表类似于:

构造函数名(参数表):

成员1(初始值),成员2(初始值),…

{

……

}

例用初始化列表初始化Tdate的month和day成员

#include

usingnamespacestd;

classTdate

{

public:

Tdate(intm,intd,inty);

protected:

intmonth,day,year;

};

Tdate:

:

Tdate(intm,intd,inty):

month(m),day(d)

{

year=y;

cout<

}

intmain()

{

Tdatebday(10,1,2003);

}

例常量和引用成员的初始化

#include

usingnamespacestd;

classA

{

intx,y;

constinti,j;

int&k;

public:

A(inta,intb,intc):

i(a),j(b),k(c),x(a)

{

y=x;

cout<<"x="<

cout<<"i="<

}

};

intmain()

{

intm=6;

Ax(4,5,m);

}

四、析构函数

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

当前位置:首页 > 高中教育 > 语文

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

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