面向对象期末整理.docx

上传人:b****8 文档编号:28341518 上传时间:2023-07-10 格式:DOCX 页数:35 大小:383.66KB
下载 相关 举报
面向对象期末整理.docx_第1页
第1页 / 共35页
面向对象期末整理.docx_第2页
第2页 / 共35页
面向对象期末整理.docx_第3页
第3页 / 共35页
面向对象期末整理.docx_第4页
第4页 / 共35页
面向对象期末整理.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

面向对象期末整理.docx

《面向对象期末整理.docx》由会员分享,可在线阅读,更多相关《面向对象期末整理.docx(35页珍藏版)》请在冰豆网上搜索。

面向对象期末整理.docx

面向对象期末整理

面向对象期末整理

第三章函数(function)

1、回文数判断

boolsymm(longn){

longi,m;

i=n;m=0;

while(i){

m=m*10+i%10;

i=i/10;

}

return(m==n);

}

2、嵌套调用

intfun1(intx,inty){

intfun2(intm);

return(fun2(x)+fun2(y));

}

intfun2(intm){

return(m*m);

}

*函数不允许嵌套定义,但可以嵌套调用。

3、递归法:

从n个人中选择k个人组成一个委员会的不同组合数。

intcomm(intn,intk){

if(k>n)

return0;

elseif(n==k||k==0)

return1;

else

returncomm(n-1,k)+comm(n-1,k-1);?

}

4、在函数被调用时才分配形参的存储单元。

实参可以是常量、变量或表达式。

传递时是传递参数值,即单向传递

5、引用是为对象取一个别名,不占存储空间。

引用类型说明符为&。

声明一个引用型变量时,必须同时使之初始化,即声明它代表那一个变量。

并且从此不可改变。

6、内联函数inline

功能简单,规模小,使用频繁的函数。

不能进行异常接口声明

7、带默认形参值的函数

√intadd(intx,inty=5,intz=6);

Xintadd(intx=1,inty=5,intz);

Xintadd(intx=1,inty,intz=6);

intadd(intx=1,inty=2);

voidmain()

{intadd(intx=3,inty=4);

add();//使用局部缺省形参值(实现3+4)

}

voidfun(void)

{...

add();//使用全局缺省形参值(实现1+2)

}

8、函数重载

9、头文件cmath

sin()、cos()、tan(),

求平方根函数(sqrt)、求绝对值函数(abs)等。

第4章类与对象

1、面向过程的程序设计方法

形式:

主模块+若干子模块。

特点:

自顶向下、逐步求精—功能的分解。

缺点:

a、程序员必须要建立起机器模型(位于解空间)和实际待解决问题模型(位于问题空间)间的联系;b、维护代价高;c、程序可重用性相对差。

2、面向对象的方法

目的:

实现软件设计的产业化。

观点:

自然界是由实体(对象)所组成。

使程序员不会受限于特定类型的问题。

程序设计方法:

使用面向对象的观点来描述模仿并处理现实问题。

通过添加新类型的对象,使自身适用于某个特定问题。

OOP根据问题来描述问题,而可以不需要根据运行解决方案的计算机来描述问题。

要求:

高度概括、分类、和抽象。

3、OOP的基本特点:

抽象

数据抽象;行为抽象(功能抽象、代码抽象)。

抽象的实现:

通过类的声明。

封装

形成“类”。

目的是增强安全性和简化编程

实现封装:

类声明中的{}

继承与派生

支持层次分类的机制。

在保持原有类特性的基础上,进行更具体和详细的说明。

实现:

声明派生类——第七章

多态性?

多态:

同一名称,不同的功能实现方式。

目的:

达到行为标识统一,减少程序中标识符的个数。

实现:

重载函数和虚函数——第八章

4、关键字protected后面声明的保护类型

与private类似,其差别表现在继承与派生时对派生类的影响不同(第七章)。

5、对象:

类类型的变量。

对象所占据的内存空间,仅用于存放数据成员,函数成员不在每个对象中存储副本

6、类外给出函数体实现:

用类名加以限定

voidClock:

:

setTime(…){…}

*也可以直接在类中给出函数体,形成内联成员函数(隐式)。

显式:

7、结构体的声明和初始化

structSavings{

unsignedaccountNumber;

floatbalance;

};

SavingsA={1,2000.0};

8、构造函数(Constructor)

在对象创建时由系统自动调用

重载构造函数的实现:

Clock:

:

Clock(intnewH)

{hour=newH;}

Clock:

:

Clock()

{hour=0;}

9、复制构造函数(CopyConstructor)

classPoint{

public:

Point(intxx=0,intyy=0){x=xx;y=yy;}

Point(Point&p);

……

};

Point:

:

Point(Point&p){

x=p.x;

y=p.y;

cout<<"复制构造函数被调用"<

}

*复制构造函数被调用的3种情况

※Pointb(a);//复制构造函数被调用

※Pointa(1,2);

fun1(a);//调用复制构造函数

※Pointg()

{Pointa(1,2);

returna;//函数的返回值是类对象调用复制构造函数

}

*默认复制构造函数:

用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员。

10、析构函数(Destructor)

完成对象被删除前的一些清理工作。

在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间。

(常量:

constfloatPI=3.14159f;)

classPoint{

public:

~Point();

};

Point:

:

~Point(){

cout<<“调用了析构函数!

”<

}

//带缺省参数构造函数

//构造函数重载

//析构函数&默认复制构造函数

//复制构造函数

11、类的组合

classLine{

public:

//外部接口

Line(Pointxp1,Pointxp2);

Line(Line&l);

doublegetLen(){returnlen;}

private:

//私有数据成员

Pointp1,p2;//Point类的对象doublelen;

};

//组合类的构造函数

Line:

:

Line(Pointxp1,Pointxp2):

p1(xp1),p2(xp2){

cout<<"Line构造函数被调用"<

doublex=double(p1.getX()-p2.getX());

doubley=double(p1.getY()-p2.getY());

len=sqrt(x*x+y*y);

}

*构造函数调用顺序:

先调用内嵌对象的构造函数,然后调用本类的构造函数。

//组合类的复制构造函数

Line:

:

Line(Line&l):

p1(l.p1),p2(l.p2){cout<<"Line复制构造函数被调用"<

len=l.len;}

intmain(){

Pointmyp1(1,1),myp2(4,5);//建立Point类的对象

Lineline(myp1,myp2);//建立Line类的对象

Lineline2(line);//利用复制构造函数建立一个新对象

cout<<"Thelengthofthelineis:

";

cout<

cout<<"Thelengthoftheline2is:

";

cout<

return0;

}

12、前向引用声明

当你使用前向引用声明时,你只能使用被声明的符号,而不能涉及类的任何细节。

第五章数据保护与共享

1、作用域:

是标识符的有效范围(函数原型作用域;局部作用域;类作用域;命名空间作用域)。

可见性:

标识符是否可以引用的问题(程序运行到某一点。

能够引用到的标识符,就是该处可见的标识符。

可见性表示从内层作用域向外层作用域“看”时能看见什么。

)。

特例:

#include

usingnamespacestd;

intmain(){

intj=1;

for(inti=0;i<5;i++){

}

cout<

/*VC6.0并未实现c++标准,而是沿用了c的习惯。

在c++标准中,上述i的作用域仅在for循环中。

*/

return0;

}

2、对类X的成员m(具有类作用域)的访问方式:

如在X的成员函数中,没有声明同名的局部变量,在该函数中,可以直接访问m;

通过x.m或者X:

:

m(x为X的实例对象);通过表达式ptr->m,(ptr为指向X类的对象的指针)。

3、命名空间作用域

用using来指定命名空间:

usingNS:

:

File;//在当前作用域中就可以直接引用File

usingnamespacestd;//在当前作用域,命名空间std中的所有标识符,都可直接引用

*具有命名空间作用域的变量,也称为全局变量

#include

usingnamespacestd;

inti;//在全局命名空间中的全局变量

namespaceNs{

intj;//在Ns命名空间中的全局变量

}

例子:

4、作用域可见性的一般规则:

标识符A、声明在先,引用在后

B、外层声明、内层无同名,则在内层可见。

C、外层声明、内层同名,则在内层不可见。

5、对象的生存期

静态生存期:

命名空间作用域中声明,函数内部声明加关键字static。

动态生存期:

局部作用域中声明。

6、类的静态成员:

用关键字static声明

描述类的所有对象的共同特征的一个数据项,对于任何对象实例。

它的属性值是相同的。

静态数据成员:

该类的所有对象维护该成员的同一个拷贝;必须在类外定义和初始化,用(:

:

)来指明所属的类。

静态成员函数:

类外代码可以使用类名和作用域操作符(:

:

)或对象名来调用静态成员函数。

静态成员函数只能引用属于该类的静态数据成员或静态成员函数。

*静态成员属于类,非静态成员属于对象。

#include

usingnamespacestd;

classPoint{

public:

Point(intxx=0,intyy=0){x=xx;y=yy;count++;}

~Point(){count--;}

staticvoidshowCount()

{cout<

//……

private:

//……

staticintcount;//引用性说明

};

intPoint:

:

count=0;//定义性说明,初始化

voidmain(){

Point:

:

showCount();////输出对象数,类名引用

 Pointa(4,5);//声明对象a

a.showCount();//输出对象数,对象名引用

//……

}

7、类的友元:

关键字friend

不同类或对象之间、类的成员函数与一般函数之间,进行数据共享的机制;

破坏了数据封装和数据隐藏。

访问对象中的成员,必须通过对象名。

//友元函数

frienddoubledist(Point&p1,Point&p2);

doubledist(Point&a,Point&b){

doublex=a.x-b.x;

doubley=a.y-b.y;

returnsqrt(x*x+y*y);

}

friendvoidTeacher:

:

setGPA(Student&s);

voidTeacher:

:

setGPA(Student&s){

s.gpa=4.0

}

//友元类

B类声明为A类的友元,

即,B类的所有函数(包括构造函数和析构函数)成为A类的友元。

类B的所有成员都能访问类A的私有成员。

友元关系:

不能传递的、单向的、不被继承的。

8、共享数据的保护(常**)

常对象必须进行初始化,且不能被更新

常数据成员只能通过初始化列表赋初值。

voidprint()const;//常成员函数声明

voidR:

:

print()const{//常成员函数实现

cout<

}

常引用:

const类型说明符&引用名

(常引用做形参,在函数中不能更新r所引用的对象)

9、多文件结构

类声明文件(.h文件)

类实现文件(.cpp文件)

类的使用文件(main()所在的.cpp文件)

10、编译预处理命令

#include包含指令:

#include<文件名>,#include"文件名"(当前目录)

#define宏定义指令

#if和#endif,#else,#elif,#ifdef,#ifndef,条件编译指令

预处理操作符—defined(返回:

0,非0)

第六章数组、指针与字符串

1、数组

数组属于构造类型。

下标表达式必须为整数。

数组名是一个常量,不能被赋值。

inta[3][4]={{1},{0,6},{0,0,1,1}};

数组名作参数,形、实参数都应是数组名,传送的是数组首地址。

Pointa[2]={Point(1,2),Point(3,4)};

2、指针

指针运算符“*”

声明:

表示声明的是指针

执行或初始化:

表示指针所指对象的内容

地址运算符“&”

声明:

表示声明的是引用。

出现在变量赋值时,出现在等号右边;或在执行语句中作为一元运算符出现:

表示取对象的地址。

int*pa,*pb=&b;pa=&a;

3、指向常量的指针:

指针类型的常量:

void*pv;int*pint;

pint=(int*)pv;

*pa就是a[0],*(pa+1)就是a[1]

cout<<*(*(array2+i)+j);

//cout<<*(array2[i]+j);

例6—11

4、对象指针声明

类名*对象指针名;

例:

Pointa(4,5);

Point*ptr;

ptr=&a;

访问:

对象指针名->成员名

cout<<(*ptr).getX();

cout<getX();

cout<

5、this指针

非静态成员函数

6、int(Point:

:

*funcPtr)()const;

funcPtr=&Point:

:

getX;

cout<<(a.*funcPtr)()<

cout<<(p1->*funcPtr)()<

cout<

cout<getX()<

7、动态内存分配

int*ptr;=newint

(2);//初值为2

deleteptr;

//数组:

int*ptr=newa[c][2];

delete[]ptr;

内存泄漏

8、头文件:

(1)动态存储分配函数:

void*malloc(size);

size:

字节数

返回值:

成功,则返回void型指针。

失败,则返回空指针。

(2)动态内存释放函数

voidfree(void*memblock);

参数memblock:

指针,指向需释放的内存。

返回值:

s=malloc(5000);/*申请内存空间*/

free(s);

9、深复制与浅复制

深复制是在浅复制基础上添加复制构造函数(内有Point*point=newPoint[size])。

例6-21,例6-22

10、字符串

string类

strcat(连接),strcpy(复制),

strcmp(比较),strlen(求长度),

strlwr(转换为小写),

strupr(转换为大写)

头文件

第七章继承与派生

1、继承的目的:

实现代码重用。

派生的目的:

当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行扩展和改进。

2、派生类的声明

classDerived:

privateBase1,publicBase2{

public:

Derived();

~Derived();

//派生类的其它成员

};

3、派生类的生产过程

吸收基类成员(除构造函数和析构函数外);改造基类成员(覆盖或隐藏);

添加新成员(核心);

4、继承方式

派生类中的成员函数不能访问基类的private成员。

基类的private成员不可直接访问。

public:

通过派生类的对象只能访问基类的public成员。

private:

通过派生类的对象不能访问基类中的任何成员。

若对象将访问该函数(如getY()),定义时写为Point:

:

getY();}

protected:

通过派生类的对象不能访问基类中的任何成员。

特点:

(水平访问)通过基类对象不能访问其protected成员。

(垂直访问)在派生类的成员函数中,可以访问其基类的protected成员。

5、类型兼容规则

替代:

派生类对象只能使用从基类继承的成员。

例子

voidfun(Base1*ptr){ptr->display();}

intmain(){

Base1b1;Base2b2;Derivedd;

fun(&b1);

fun(&b2);

fun(&d);

}

结果:

Base1:

:

display()

Base1:

:

display()

Base1:

:

display()

6、派生类的构造函数

调用基类的构造函数初始化;

初始化派生类新增的成员对象;

执行派生类构造函数体。

C:

:

C(inti,intj):

B(i),c(j){}

多继承且有内嵌对象时:

classC:

publicB2,publicB1,publicB3{

public:

//派生类的公有成员

C(inta,intb,intc,intd):

B1(a),memberB2(d),memberB1(c),B2(b){}

private:

//派生类的私有对象成员

B1memberB1;

B2memberB2;

B3memberB3;

};

7、派生类的复制构造函数

Derived:

:

Derived(constDerived&v):

Base(v){…………}

8、继承时的析构函数

在6的例子的三个基类中声明析构函数,系统会自动隐式调用。

9、派生类成员的标识与访问

同名隐藏原则。

如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定。

d.B1:

:

var=2;

d.B1:

:

fun();

10、二义性问题

多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性(不确定性)——采用虚函数或同名隐藏原则来解决。

第八章多态性

1、多态性:

发出同样的消息,被不同类型的对象接收时,导致完全不同的行为。

多态是对类的特定成员函数的再抽象。

消息:

对类的成员函数的调用。

绑定(binding):

是指计算机程序自身彼此关联的过程。

绑定确定程序中的操作调用与执行该操作的代码间的关系。

静态绑定:

绑定工作在编译连接阶段完成。

如:

重载、强制和参数多态

动态绑定/晚期绑定:

绑定在程序运行阶段完成。

2、运算符重载:

对已有的运算符赋予多重含义(以适用于用户自定义类型)。

不能重载的运算符..*:

:

?

:

经重载的运算符,其操作数中至少应该有一个是自定义类型。

声明形式

返回类型operator运算符(形参){

......

}

重载为类成员函数时:

参数个数=原操作数个数-1(后置++、--除外)

重载为非成员函数(一般声明为类的友元函数):

参数个数=原操作数个数

Complexoperator+(constComplex&c2);

//+重载为成员函数

ComplexComplex:

:

operator+

(constComplex&c2){//重载函数实现

Complexc;

c.real=c2.real+real;

c.imag=c2.imag+imag;

returnComplex(c.real,c.imag);

}

//

friendComplexoperator+(constComplex&c1,constComplex&c2);//运算符+重载

friendostream&operator<<(ostream&out,constComplex&c);//运算符<<重载

Complexoperator+(constComplex&c1,constComplex&c2){//运算符+重载

return

Complex(c2.real+c1.real,c2.imag+c1.imag);

}

ostream&operator<<(ostream&out,constComplex&c){//运算符<<重载

out<<"("<

returnout;

}

/*前置单目运算符,重载函数没有形参;

对于后置单目运算符,重载函数需要有一个整型形参。

*/

Clock&Clock:

:

operator++(){

//前置单目运算符重载函数

second++;

……

return*this;

}

ClockClock:

:

operator++(int){

//后置单目运算符重载

Clockold=*this;

++(*this);

returnold;

}

**程序运行结果为:

Firsttimeoutput:

23:

59:

59

myClock++:

23:

59:

59

++myClock:

0:

0:

1

3、虚函数virtual

虚函数是动态绑定的基础。

是非静态的成员函数。

具有继承性,本质:

是覆盖

*

实现这种动态的多态性,必须使用基类类型的指针变量或引用,使该指针指向不同的派生类的对象,并通过调用指针所指的虚函数才能实现动态的多态性。

派生类中定义的虚函数,必须与基类中的虚函数同名,参数的类型、顺序、个数必须一一对应。

只有类的成员函数才能说明为虚函数,普通函数不能说明为虚函数。

一般内联函数不应是虚函数,因为内联函数是在编译时决定其位置。

构造函数不能是虚函数。

析构函数可以是虚函数。

4、纯虚函数

这样基类中就可以不需要给出函数的实现部分。

5、抽象类

抽象类只能作为基类来使用,不能声明对象,

可以定义指针或者引用

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

当前位置:首页 > 教学研究 > 教学计划

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

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