搜索
您的当前位置:首页正文

最完整的C++资料

来源:小奈知识网
总共15张纸,应该也不算特别多的。不敢说很好,但看了总比没看好吧,希望大家的考试都是一路绿灯,加油!! C++考前复习简略知识点 第五章数组与指针

1,数组不能进行整体访问和处理,比如要输出数组,不能使用cout<2,数组做为函数的参数时,一维数组[ ]中是空的,多维数组只可省略最高维

3,再次强调,有n个数据的数组,下标是从0到n-1,所以循环语句应该写为for(i=0;i4,在对指针进行操作前,一定要确定指向,否则产生严重后果 5,指针常量和常量指针

指针常量 例:int *const p;指针的指向不能改变,但是值可以变

常量指针 例:const int *p;指针的指向可以改变,但是那个值不能改变 这个有点不太好记忆,常量指针重点是常量,值不能变

6,this指针是指向对象的,this指针不一定都要写成显示的,静态成员函数没有this指针

7,数组名是首元素的地址,大家都知道,但是不能用a++这样的形式来指向a[1],因为数组名可以理解为是一个指针常量,指向不能改变。

8,指针相减,如果*p1和*p2是分别指向a[2]和a[6]的指针,那么p2-p1就等于4,中间的数组元素的个数,还有,指针相加是无意义的

9,指向多维数组的指针比较复杂,还是记几个例子吧(用->代表文字指向,但是语法上是错的哈)

Int b[4][4] b+3->b[3]这里我的理解就是二维数组是由一维数组作为元素的数组,所以指向的是整个第三行

*(b+3)->b[3][0] *(*(b+3))=b[3][0]

*(b+3)+3->b[3][3] *(*(b+3)+3)=b[3][3] 理解很重要。。。

10,指针做函数参数,实参必须是地址或者数组名;引用做函数参数,实参必须是变量或对象本身。实参为数组的时候,只能用指针而不能引用,因为数组的引用不存在

11,函数的返回值如果是指针的话,那么它所指向的那个数据生命期不应该只在函数中,所以应该是全局变量等(我只知道个全局变量。。。) 12,一些比较常用的字符串处理函数strcat---catenate(连接) strcmp----compare(比较)

strcpy---copy(复制) strlen---length(长度)头函数名#include 当然处理字符串用string类是最方便的啦,头函数名#include

第六章 模板与数据结构

13,模板参数名要是正确的标识符,以字母或_开头,包含字母、数字、字符,不会与会变蓝色的关键字重名

14,对半查找法,关键的地方就在于low=mid+1 和high=mid-1,以及最开始的mid= -1赋初值,升序对半插入排序法类似

15,升序直接插入排序法,从第一个开始循环,与它前面所有的元素一一比较,直到找到第一个比它小的,排它后面。注意,查找与移动同时进行

16,冒泡排序法,两两比较,依次将小的数推前,注意布尔数noswap的用法,开始置t

ure,有交换的话置false,判断循环的条件就是if(noswap)

17,直接选择排序,从第一个开始循环,找出它后面的最小的那个元素,和其交换 18,指针数组,例*name[7],每个元素都是一个指针,比二维数组节省空间 O N E T W O T H R E E

如果用a[3][5]的二维数组,则要浪费4个存储单元

19,当一个函数需要将另一个函数作为参数的时候,必须借用指向函数的指针,因为函数本身不可以做参数

定义一个指向函数的指针,并初始化,例

int (*pf)(char*,char*)=scopy;

其中函数名scopy就是该函数的入口地址,类似于数组名是数组存储区域的开始地址 20,指向类成员的指针,必须指明属于哪个类,例

Float(Student::*pf)()=Student::SetScore;则该指针指向了Student类里的成员函数SetScore,语句student1.*pf就相当于调用了student1.SetScore 同样也有指向数组成员的指针

21,由于静态成员函数没有this指针,所以指向静态成员函数的指针是普通指针

第七章 动态内存分配

22,new运算符返回的是一个指向所分配类型变量(对象)的指针,必须显式初始化。例 int *p=new int(5);

P为指针变量名,5是初始化式

23,delete释放的是指针所指的目标的内存空间,但指针本身依然存在,该指针本身所占内存空间并未释放

24,撤销动态数组的空间时,注意方括号[]的使用 delete []p 撤销整个数组

delete p 只撤销数组的第一个元素

25,用动态分配来定义数组的最大优点就是,大小可以根据实际需要来更改,不像静态分配,经常“大开小用”,浪费内存空间 例cout<<”请输入动态数组的元素个数”<Cin>>n;

p=new char[n]; 根据实际需要申请内存空间

由于n的大小随时改变,所以没有对应的初始化式,不可对数组进行初始化,与静态数组不同

26,动态分配申请失败,new操作符就返回一个空指针NULL,撤销了目标后,p本身并没有消失,并且成为了一个没有指向任何有效地址的空悬指针,建议将p置空NULL 27,delete要跟new配套使用,如果new返回的指针值丢失,那么分配的自由存储空间就无法回收,造成内存泄漏。重复释放的话也是危险的,第一次释放后该空间可能已经分配给新的对象,再一次释放则会使新对象丢失,所以释放后应该把p置空

28,在哪个域使用的new建立的空间,则应该在相同的域用delete进行释放,例,在函数内建立,而在函数外释放是很容易出错的

29,通过new建立的对象要调用构造函数,通过 delete删除对象也要调用析构函数 由于构造函数有参数,所以new后面的类类型也可以有参数,这些参数即构造函数的参数。例CGoods*pc,*pc2;

Pc=new CGoods(“夏利2000”,10,118000);调用三参数的构造函数 30,但是创建数组时,则没有参数,只能调用默认的构造函数,例 pc2=new CGoods[n];(pc2在29中已定义)

调用了n次默认构造函数,如果没有默认的构造函数,则不能创建对象数组

31,为了更好的解释浅复制和深复制,先介绍一般的复制构造函数,简单说就是用同一个类的对象来初始化另一个对象,例Student::Student(Student &c),其参数采用的是同类对象的引用,必须使用一个已产生的同类对象做实参。功能是依次完成对象中对应成员数据的复制

例CRect::CRect(CRect &c){left=c.left;top=c.top;right=c.right}

32,浅复制,有的对象中不只是有数据成员,还有指针成员,则类的对象进行数据复制时,就会出现不同对象的同一指针成员指向同一个由new动态生成的存储区域,如在不同路口指向同一建筑的两个路牌,当用delete把“路牌1”(*p1)所指向的“建筑”(自由存储空间)撤销后,“路牌2”(*p2)所指向的“建筑”(„„空间)实际已经不存在了,再用delete撤销该“建筑”(„„空间)则会产生错误

33,为了解决浅复制的问题,就有人想出了深复制。。。

重新定义复制构造函数,给每个对象分配一个独立的自由存储区,即每个路牌指向的都是独立的建筑,必须自定义复制构造函数和析构函数以释放动态分配的内存

34,析构函数的调用顺序和构造函数是相反的,例 分别对对象S1 S2 S3调用构造函数,则按S3 S2 S1的顺序调用析构函数

35,链表,建立在自由存储区中,表头head在使用中必须妥善保管,不能丢失,否则整个链表会丢失,内存也会发生泄漏

36,释放所有结点的语句 p1=head;head=p1->next;delete p1;

其中head=p1->next是将下一个结点作为表头,则可以依次从前删除结点,直到最后一个 37,在书本244页的例7.8中,有一个头文件#include,查阅百度百科后得知,这是“断言”的头文件,在245页的第5行中,使用了断言assert函数,该函数的作用就是判断是否符合条件,不符合就中止程序,该函数的缺点是,使用多了会极大的影响程序的性能,增大程序开销

38,栈是在一头进,同一头出的线性表,有“先进后出”的特点。队列就是在一头进,另

一头出的线性表,特点是“先进先出”。二叉树就不说了。。我也不愿意看了。。

第八章 继承与多态

39,派生类完全保存了基类的数据成员和函数成员(除了构造函数和析构函数),并且还新增了自己的成员

40,派生出的新类同样可以做为基类派生出新的的派生类,一个基类也可以派生出多个派生类,打个比方。。在单继承中,一个父亲可以有很多个孩子,而孩子又会有孩子,则父亲是直接基类,祖父或曾祖父等更高辈分的就是间接基类。多重继承中就是一个孩子有多个父亲。。。。

41,但是有些基类的成员在派生类中是不需要的,则新添加的派生类成员中包括通过屏蔽作用取代基类成员的更新成员,做法是在派生类中声明一个和某个基类成员同名的成员,则派生类中的成员屏蔽了基类同名成员,如果成员函数,参数表和返回值也完全一样,则称为同名覆盖,否则为重载

42,发展新函数才有了派生的意义,否则只是基类的简单复制,人类就没有进化了。。。 43,派生类中的构造和析构函数必须要重写,因为这两种函数没有继承,不管基类中的这两个函数是否一样试用于派生类,都要重写

44,继承方式是记忆比较容易混淆的。下面用比较直观的来增强记忆 (1)公有派生:父亲的公有文件,儿子和外人都可以看,私有文件只有父亲一个人能看(只能通过基类中的公有成员函数去访问基类的私有成员),保护文件只在家族内部传看,父亲儿子都可以看,但是外人看不到(公有和保护成员在派生类中的属性不变)

(2)私有派生:儿子依旧可以看到父亲的公有和保护文件,私有文件也依旧不能看,和公有派生不一样的地方是,所有的成员在派生类中都变成了私有的,即父亲把所有文件都交给了儿子保密,因此外人是不能看到父亲的任何文件的(类外只有通过派生类的公有成员函数去访问基类的成员)

(3)保护派生:基类的私有函数依旧是派生类的私有函数,不可直接访问,而基类中的公有的和保护成员全部为派生类的保护成员,在派生类中可以直接访问。从这里看,和私有派生没什么区别。但如果是多层派生,那么这个派生类又做为新的基类,派生出了新的派生类,就有区别了。比方说是,私有派生,儿子只能看到父亲的文件,但在保护派生中,儿子可以看到祖父甚至曾祖父曾曾祖父的文件。

45,派生类的构造函数,不继承并不代表不利用,只是把基类的构造函数当作派生类的构造函数的一部分,参数总表中要有类型名,而后面的参数名表则不需要,因为其是实参表 如果基类没有定义构造函数,则派生类也可以不定义,但是一旦基类定义了带有形参表的构造函数,派生类就应当定义构造函数

46,析构函数是先析构派生类中的成员,最后析构基类的成员

47,虚基类的作用就是在多重继承中,如果有一个基类是多个派生类的基类,那么这个基类就会被建立多次,浪费空间,解决办法就是将这个共同基类设置为虚基类,写法是在派生的时候,在基类名前加上virtual.例 class Employee:public virtual Person{„„};

48,有关虚基类的构造函数,调用的首先是虚基类的构造函数,首先建立虚基类,而且只建立一次,如果是非虚基类的话,按照常理,是应该建立多次的,而且是它派生了几个类,就应该建立几次

49,赋值兼容规则:再多谈谈公有派生,因为其是应用最广泛的主流.。派生类的访问限定和基类完全一样,所以基类能解决的问题,公有派生类也都能解决,在任何需要基类对象的地方都可以用公有派生类的对象来代替。

50,继承与聚合:把基类的对象当作一个新类的对象成员。 例 classA{public:int K„„};

class B;public A,public A{„„};(继承了两次)

是不对的,因为这样的话类B中的两个K是无法分辨出来的,如果一定要用两个K,则采用成员对象

class B{A a,b;„„};这样B中的两个K,a.K和b.k就可以分辨了

51,多态性分为编译时的多态性和运行时的多态性。编译多态性通过函数重载和运算符的重载来实现。运行多态性是在程序执行前,无法根据函数名和参数来确定该调用哪一个函数,必须在执行中看情况来动态决定,这种多态性是通过类继承关系和虚函数来实现的 52,虚函数是类的成员函数,不能是友元函数,或静态成员函数,不能将构造函数定义为虚函数,因为这时候对象还没有实例化,但是析构函数可以成为虚函数,实现撤销对象时的多态性。当一个类的某个成员函数被定义为虚函数的时候,由该类派生出来的所有派生类中,该函数始终保持虚函数的特性,重新定义时不仅要同名,参数表和返回类型也要与基类中的虚函数一样

53,虚函数的作用挺抽象的,与前面提到的屏蔽基类同名函数有关,如未加关键字,则就是同名覆盖函数,不能实现运行时的多态性,在看例子的过程中,发现直接传递值给对象,是不要应用到虚函数的,属于编译时的多态性,而用指针,引用一类的来指向基类的对象时,由于多态性,以及定义的成员函数,指针会自动指向派生类中的对应的成员函数(个人比较肤浅通俗的理解。。。。错了多包涵- -#)

54,如果一个类只能用来派生出新的类,而不能用来定义对象,那么该类成为抽象类,由前面可知,如果把一个类的构造函数或者析构函数弄成保护形式时,这个类就成为了抽象类

55,包含纯虚函数的类就是抽象类,纯虚函数在基类中不能实现,因为无法定义对象,其实现依赖于不同的派生类,函数声明为 virtual 返回类型 函数名(参数表)=0;

这里的=0实质上是将指向函数体的指针定义为NULL,派生类中必须重新定义纯虚函数的函数体,才能来定义对象

56,纯虚函数和抽象类有什么作用呢,其目的就是建立一个类的通用框架,其本身可能没什么实际作用,但它起到一个指示作用,用来引导建立一系列结构完整的派生类

第九章 流类库的输入/输出

57,整个流类体系是一个派生类,其基类为抽象类,所有派生都是公有派生

58,cin,cout,cog,cerr四个全局文本流对象,cin用来从键盘输入的,cout是输出到显示屏上的,cog和cerr成为标准错误输出流,这四个里面只有cerr是非缓冲区流,一旦发生错误,就立即显示。我的记忆方法就是cerr中的‘r’代表rapidly,很快显示就是没有缓冲啦

59,对缓冲区流cout 和cog来说,仅当输出缓冲区满时才将缓冲区中的信息输出,加endl的作用就是清空缓冲区,立即显示。对输入cin而言,仅当输入一行结束时才开始从缓冲区中取数据,所以在按下回车键之前,输入数据都是可以修改的

60,输入错误的话,则在流的状态字state中对应位置1,此后忽略所有对该流对象的操作,必须用clear清0,然后才能继续进行,要提高程序的稳健性,就要在编程中加入对状态字state的判断

61,输入数后再输入字符或字符串,如果数后直接加回车,则应该使用cin.getline()提取回车。如果还有空格,则要读空缓冲区。

62,’+’作为一个双目运算符,在3+5中,3是左操作数,5是右操作数

63,运算符的重载,如果是单目运算符,则无参数。如果是双目运算符,则只有一个参数,且作为运算符的右操作数,而左操作数是类的对象。

64,重载插>>和提取<<运算符。流用作函数的参数时,规定采用引用调用,不用传值调用。因为这里要求处理流本身,而不是副本。第一个参数是流的引用,是运算符的左操作数,第二个参数是类的引用,做为右操作数,函数返回的是流,也可以返回流的引用 例 friend istream&operator>>(istream&,calssName&)

friend ostream&operator<<(ostream&,calssName&)

65,根据文件内容的数据格式可分为两类:文本文件和二进制文件。在文本文件中存取的最小信息单位为字符,二进制文件中存取的最小信息单位为字节

66,对文件进行读/写实际上是受到一个文件定位指针(file position pointer)的控制,输入流的指针也叫做读指针,同理,输出流的指针叫写指针,且这两个指针都会自动向文件尾移动。

67,说明一个文件流对象,格式为 #### ifile/ofile/iofile;(分别对应三种情况) 若只输入,则####为ifstream,只输出为ofstream,既要输入又要输出,为fstream, 68,打开文件 例iofile.open(“myfile.txt”,ios::in|ios::out);

ios::in|ios::out这句说明该文件即要用来输入也要用来输出,除了in,out还有其他的一些标识,

trunc清空这个文件

app若不存在这个文件则生成一个空文件,如存在,则把新数据接在原数据尾部

69,文件读到结束,已无数据可取,则eofbit置1,输入流结束,在书本327面第2行的sfile.eof()!=1就是用来判断是否已到文本结束地方的,第3行的sfile.rdstate是读取状态字的,前面说过,正常时状态字是0,出错状态字置1 70,书本327面例题9.9源代码,

#include #include #include #include

using namespace std; class inventory{ string description; string no; int quantity; double ccost; double retail; public:

inventory(string=\"#\ friend ostream &operator<<(ostream&dist,inventory&iv); friend istream &operator>>(istream&sour,inventory&iv); };

inventory::inventory(string des,string no,int quan,double cost,double ret){ description=des; quantity=quan; ccost=cost;

retail=ret; }

ostream &operator<<(ostream&dist,inventory&iv){

dist<dist<istream &operator>>(istream&sour,inventory&iv){

sour>>iv.description>>iv.no>>iv.quantity>>iv.ccost>>iv.retail; return sour; }

int main(){

inventory car1(\"夏利2000\ inventory motor1(\"金城125\ ofstream distfile(\"e:\\\\ex9_9.data\"); distfile<ifstream sourfile(\"e:\\\\ex9_9.data\"); sourfile>>car2>>motor2; sourfile.close(); cout<} (打错是难免的。。这个时候头脑已经不清醒了。。输出结果的截图发不上来。。大家自己试试吧)

71,使用二进制文件可以控制字节长度,读/写数据时不会出现二义性,可靠性高

72,文件与对象。文件应该在构造函数中打开,在析构函数中保存和关闭,并撤销对象,这样,与动态安排的其他资源一样,当撤销对象时,能自动释放资源

呼呼~~终于结束了,看了一晚上,难免头脑发热一下看错打错理解错,好的地方大家就学习下,不好的地方就当改错题做了。不要觉得很多,我写完了,大家看完应该没有问题的吧。加油加油!!西嘎嘎不挂万岁!!

----------Lemon

因篇幅问题不能全部显示,请点此查看更多更全内容

Top