与C + +握手; (第二部 高级功能) 欢迎大家的光临 (96分)

  • 主题发起人 主题发起人 Tense
  • 开始时间 开始时间
T

Tense

Unregistered / Unconfirmed
GUEST, unregistred user!
与C + +握手
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第八章 指针
目的:指针以及指针的使用;自由存储以及如何处理内存;
时间: 2001/12/13 17:18:10--> 2001/12/13 18:06:23
8.1 指针
指针: 保存内存地址的变量;
一定要对指针初始化;
运算符(*): 间接引用运算符;当一个指针被间接引用时,就读取所保存的地址处的值;
间接引用运算符(*)在两种情况下使用:
声明: 当声明指针时,“*”表示它只是一个指针,而不是普通变量;
如: int *pAge = 0;
间接引用: 表示访问存储在指针中的内存地址处的值;而不是地址本身;
如: *pAge = 5;
 
指针的用处:
处理自由存储区的数据;
访问类的成员数据和函数;
通过引用的方式向函数传递变量;
栈和自由存储区;
内存的五个区域:全局名字空间、自由存储区、寄存器、代码空间、栈;
自由存储区:
自由存储区: 局部变量和函数形参位于栈中、代码位于代码区、全局变量位于全局变量区;
寄存器用于内存管理(例如保存栈顶指针和指令指针等);
所有的剩余空间被称为自由存储区,有时也被称为堆;
在程序结束前,不会被清除;
优点: (1)保存的数据可以一直使用除非显式的释放他们的内存空间;
(2)只有使用特定指针的函数才能够访问特定的数据;
栈:在函数返回时会被自动清除;
new: 分配自由存储区中的内存;
delete: 释放内存;把内存释放给自由存储区;
备注: 指针
(1)本身是一个局部变量(与所指向的内存区域不同),当声明函数的指针返回时,指针的作用域结束被释放;
(2)使用new分配的内存不会自动被释放,于是这块内存不能由其他数据使用(称之为内存泄露);
这时,要使用delete把内存释放给自由存储区;
内存泄露: 两种情况;
使用new分配的内存不会自动被释放,于是这块内存不能由其他数据使用;
在没有删除一个指针之前,就对其重新赋值;
指针this: 一个指向对象自身的指针;
-> : 成员指针运算符; 访问对象的成员;
迷途指针(失控指针、悬浮指针): 当一个指针调用delete,释放所指向的内存,但并没有设置为空;
删除一个指针后,应把该指针设置为空;
const指针: 在指针之前或之后可以使用关键字const;
之前: const int *pOne; pOne是一个指向整型常量的指针;该指针指向的值是不能改变;
之后: int * const pTwo; pTwo是一个指向整型常量的指针;该指针指向的整数可以改变;
但pTwo这个指针不能指向其他变量;
都有: const int * const pThree; pThree是一个指向整型常量的指针;指向的值不能改变;
并且pThree这个指针不能指向其他变量;
注意
const int *p1;
//the int point to is constant;
int * const p2;
//p2 is constant, it can't point to anything else
;
建议:
一定要使用const保护不应改变的通过引用传递的对象;
当对象可以改变时,一定要通过引用传递;
当小的对象不应改变时,要用值传递;
8.2 总结:
用处: 指针提供了一种访问数据的强有力的手段;
变量: 指针可以存储地址;每一个变量都有自己的地址,可以通过取址运算符(&)获得;
声明: 指针通过写出它们指向的对象的类型来声明,后接间接运算符(*)和指针名;
初始化: 指针应被初始化指向一个对象或者置为0(空指针);
访问: 通过间接运算符(*)访问由指针保存的地址所存储的值;
const指针: 不能被重新分配来指向其他对象,也不能用来改变他们指向的对象;
new: 建立一个新对象,并把返回地址赋给指针;
delete: 释放内存空间;但并没有毁坏指针
注意: 在指针指向的内存被释放后,必须对它重新赋值;
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第九章 引用
目的:引用以及如何使用、引用的限制;引用和指针的区别是什么; 在值、对象以及函数中的使用;
时间: 2001/12/15 14:36:20--> 2001/12/15 17:26:40;

9.1 引用
引用: 是目标的别名;
当声明一个引用时,应该把它初始化为另一个对象名,也就是目标;
引用是目标的替代名,所有对引用的操作实际都是对目标的操作;
格式: 类型名 引用运算符(&)和引用名; 如 int &rSomeRef = intOne;
常常使用以"r"开头的引用名;
对引用重新赋值,相当于对目标重新赋值; 引用不能为空;
必须用引用来创建对象的别名;必须初始化所有的引用;不要向引用重新赋值;
任何对象都可以被引用,包括用户定义的对象;(不是对类的引用);
使用对象的引用与使用对象本身一样,对于编译器的内置类型也是如此;
9.2 函数参数
函数: 在函数的作用域中创建一个实参的拷贝;
有两个限制,如下;
使用值传递参数;
返回语句只能返回一个值;
引用传递函数参数:直接把原对象传递给函数;能够改变被引用的对象;
使用指针: 使用指针通过引用传递;
使用指针形参指向原值;
把一个指针传递给函数,实际就是传递对象的地址,函数处理该地址所保存的值;
使用引用: 使用引用通过引用传递;
使用原值的引用作为实参传递给函数;
引用使普通变量的使用更加方便和容易,并且具有指针的功能和使用引用传递参数的能力;
9.3 小结:
引用以及和指针的比较;
引用必须被初始化为对一个存在的对象的引用,而且不能被重新赋值去引用其他的对象;
使用引用传递的方式传递参数比使用值传递的方式效率更高;
引用传递改变被调用函数的实参的值;
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第十章 高级函数
目的:如何重载成员函数,如何重载运算符,函数的编写以及动态分配变量的类;
时间: 2001/12/19 15:53:30--> 2001/12/19 18:06:23;

10.1 重载成员函数:
重载: 同样的名字不同的参量编写两个或多个函数来实现函数的多态性或函数重载;
函数重载:以下情形使用函数重载(有时使用函数默认值较好)
没有合理的默认值;
需要不同的算法;
需要在参量表中支持各种类型;
构造函数: 在构造函数内有赋值或操作语句,但是最好尽可能使用初始化;分2个阶段调用;
初始化阶段: 初始化成员变量更清楚而且效率更高; 如下:
Rectangle::Rectangle(): //constructor name and parameters;
itsWidth(5), //initialization list
itsLength(6)
{ //body of construtor
}
函数执行阶段:
备注: 一些变量必须被初始化而不能被赋值(如常量和引用);
复制构造函数: 在每次复制一个对象的时候调用;
必须有一个参数,即对同一个类的对象的引用;
使用常量引用比较好,因为这样构造函数就不必改变传递进来的对象;
成员复制(浅拷贝): 把每一个成员变量复制到新对象的成员变量中去;
深层复制: 把堆上的分配的值复制到新分配的内存中;
10.2 运算符重载
运算符重载: 允许用户把运算符添加到自己的类中;
重载前置运算符: returnType Operator op (paramereters) //op是要重载的运算符;
声明一个重载的运算符就象声明一个函数一样,用关键字“operator”后面跟要重载的运算符;
单目运算符函数不带参数,但后置自加和自减运算符除外,要带有一个整型变量作为标志;
如1: void operator ++ ();
如2: const Counter&
Couter::operator ++();
如3: Counter Counter::operator --(int);
重载运算符的返回类型: 返回一个对象以便赋给另一个对象;
使用this指针:
重载后置运算符: 要使用临时对象返回,要按值传递;
运算符重载的局限性:
作用于内置的运算符不能重载;
运算符的优先级和运算符的目不能被改变;
不能创建新的运算符;
10.3 小结
类成员函数的重载,以及为函数提供默认值;以及两者的差别;
重载类构造函数可以从其他的类中创建灵活的类;
对象的初始化发生在构造函数的初始化阶段;与构造函数内赋值相比,初始化更有效;
this指针指向当前对象,对于所有成员函数都是不可见的参数;
间接引用的this指针常常通过重载运算符返回;
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第十一章 继承
目的:继承、派生、保护访问、虚函数;
时间: 2001/12/20 16:55:30--> 2001/12/20
11.1 继承和派生
派生: 向已有的类添加了新功能后的类叫做原来类的派生;原来的类叫新类的基类;
通过派生类来扩展测试类的功能;
通过覆盖基类方法来改变派生类中某些函数的行为;
三种访问限定符:
公有型(public): 公共的;
保护型(protected): 数据对于当前类和这个类的派生类是可见的,而对于其他类是不可见的;
私有型(private):只对当前类是可见的;
重载和覆盖:
重载: 同样的名字但不同的签名创建了多个方法;
覆盖: 在派生类中用和基类中的方法相同的名字和相同的签名创建了一个方法;
不能通过改变函数名来隐藏基类函数;
11.2 虚函数
注意:
如果从一个类中派生另一个类,必须使用虚函数;
如果任一个函数是虚函数,那么析构函数必须是虚函数;不能把构造函数标记为虚函数;
11.3 总结
派生类以及如何从基本类中继承;
公有继承和虚函数;
类将继承基类中的所有公有的和保护型的数据和函数;
三种访问机制;
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第十二章 数组和链表
目的: 数组以及特性;字符串;数组和指针;
时间: (2002/12/24 15:22:20pm-2002/12/24 18:33:28)
12.1 数组
数组: 存放地址的集合;每个地址保存相同类型的数据;
数组名: 是指向数组的第一个元素的常指针;
固定大小的相同类型的对象集合;数组不做边界检查;
每个存储地址叫做这个数组的一个元素;
数组元素从0开始;一个有n项的数组序号从0到n-1;
尽量使用指向数组的指针来表示下标;
初始化数组: 如:int IntegerArray[3] = {10,5}没有被初始化的数组元素会被初始化为0;
对象的数组: 下标运算符[]确定数组成员;成员运算符(.)来访问特定的成员变量;
多维数组: 如 int theArray[2][3] = {{1,2,3},{11,12,13}};

12.2 指针和数组:
指针数组: 在自由存储区上声明每一个对象,然后把指向对象的指针存放到数组里;
指向数组的指针和指针数组:
CAT FamilyOne[500] //一个由500个CAT对象组成的数组;
CAT * FamilyTwo[500];
//一个500个指向CAT的指针组成的数组(指针数组)
CAT * FamilyThree = new CAT[500] //一个指针指向500个CAT对象组成的数组;FamilyThree是一个指向数组的指针;
//FamilyThree是FamilyOne的一个变量,但与FamilyTwo不同;
堆: 把整个数组放在自由存储区中,称为堆;通过调用new和下标运算符来实现;
CAT * Family = new CAT[500];
//声明Family为一个指向500个CAT对象组成的数组的首地址;
CAT * pCAT = Family;
//pCAT指向Family[0];
pCAT->SetAge(10);
//把Family[0]赋值为10;
pCAT ++;
//指向Family[1];
pCAT->SetAge(20);
//把Family[1]赋为20;
删除自由存储区中的数组: 运算符 delete [] ([]告诉正在删除数组)
char数组:
字符串: 是一个以空字符“/0”结尾的一个字符数组;
cin.get()可解决缓冲区以及空格的问题;
strcpy、strncpy: 内容复制;
链表:
可以管理不知大小的集合;
可创建任意数目的复杂的数据结构;
数组类:
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第十三章 多态性
目的:多重继承;虚继承;抽象数据模型;纯虚函数;
时间: (2001/12/25 16:04:20->2001/12/25 17:43:36)
13.1 多重继承
多重继承: 从多个基类派生一个新类;
当一个新类需要从多个基类中继承函数和特征时必须使用多重继承;
当派生性最强的类必须只有共享基类的一个实例时,必须使用虚继承;
当用虚基类时一定要初始化派生性最强的类的共享基类;
13.2 虚继承
抽象数据类型:一个抽象数据类型代表一个概念而不是一个对象; 
纯虚函数:
[第8章 指针][第9章 引用][第10章 高级函数][第11章 继承][第12章 数组和链表][第13章 多态性][第14章 特殊类和继承]
第十四章 特殊类和函数
目的: 静态成员变量、静态成员函数、函数指针、成员函数指针、函数指针数组;
时间: (2001/12/26 10:41:30--->2001/12/26 12:20:23)
14.1 静态成员
静态成员变量: 在一个类的所有实例中是共享的;
静态成员变量必须在类声明外部定义和初始化;
静态成员数据是每个类一个;成员数据是每个对象一个;
静态成员变量不是对象的一部分,因此声明时不会分配内存;实例化时没有留出存储空间;
静态成员函数: 存在于类的作用域之内;可以在没有这个类的对象的情况下调用;
静态成员函数没有this指针,不能声明为const;
静态成员函数不能访问任何非静态成员变量(成员数据变量在函数内通过this指针访问);
14.2 函数指针
函数名: 指向函数的常指针;(数组名是指向数组第一个元素的常指针);
函数指针:
注意指针所指向的对象类型;
指向函数的指针必须有一个正确的返回类型和签名的函数;
long * Function(int): 带有整型参数并返回一个指向长整型变量的指针的函数;
long (* Function(int)): 指向函数的指针,该函数带有一个整型参数并返回一个长整型变量;
VPF: 在函数指针数组中使用typedef表示 void(*)(int &, int &)
函数指针数组
14.3 成员函数指针
成员函数指针: 要有正确的类对象,和函数指针用法相同;
成员函数指针的创建: 要包含类名和作用域运算符(:); 如 void (Rectangle:: pFunc)(int, int)
调用是针对他的函数;
参考书籍: Jesse Liberty Teach Yourself C + + in 21 Days(Third Edition);
编译器: VC++6.0
(第一部 http://www.delphibbs.com/delphibbs/dispq.asp?lid=782535)
如有什么不正确之处,请指点,谢谢大家;
 
good
addoil
 
缺少例子,
 
正在学习C++,一起学习、交流如何?
 
指针永远是热点~~~
 
学习中....
 
呵呵,我已经看完了第一部了。现在又来第二部真好呀。[:D]
顺便问一下有第三部吗?
 
gzgzgzgzgzgz……
 
多人接受答案了。
 
后退
顶部