c++ primer study note.doc_第1页
c++ primer study note.doc_第2页
c++ primer study note.doc_第3页
c++ primer study note.doc_第4页
c++ primer study note.doc_第5页
免费预览已结束,剩余15页可下载查看

下载本文档

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

文档简介

M*a*i*l*l*o*v*e.*c*n1)2) 关于文件格式标准c+头文件是没有后缀名的,原因是不同的实现产品的头文件格式不一致.c格式的是c程序的文件,但在unix中却被当作是c+程序的文件.Include 一般引用工程文件和标准头文件,可以更改系统设置的默认路径;”一般引用自定义头文件,会从当前目录下开始找。3) 并不是所有c+实现都支持命名空间,所以在不支持的里面用using是会报错的.4) 无论是一种语言还是它的标准库都不可能提供实际程序设计环境要求的所有数据类型。因此现代语言都提供了类型定义工具设施使我们能够在语言中引入新的类型这些类型的用法与内置类型的用法一样方便在C+中这种设施就是类机制。5) #ifndef 没有定义,#ifdef如果定义了,前者用于避免重复包含宏.6) 在编译标准c+的时候会自动定义_CPLUSPLUS,而编译c的时候会自动定义_STDC_7) 预定义名字,_LINE_记录文件已经被编译的行数,_FILE_记录正在被编译的文件的名字._TIME_ 编译文件的时间;_DATE_编译文件的日期.8) 断言assert()定义在c语言中的头文件,在c+中是cassert.9) c+一等公民(first class ) 包括整型等但不包括数组类型10) 指针的类型都是整形,因为存放的值是内存地址。而指针指向的类型可以是多种类型。11) 用指针来间接操作变量并没有什么好处,比直接操作变量名字的效率低而且容易错.指针的作用应该是管理和操纵动态分配的内存.12) 静态与动态内存分配,静态对象是有名字的变量,动态对象是没有名字的变量,只能通过指针操作.静态对象的分配与释放有编译器自动完成。动态对象必须通过new和delete表达式显示管理。13) 内存泄漏(memory leak)是指一块动态分配的内存,而拥有这块内存的指针已经丢失。没有办法继续使用这块内存。14) c+不允许成员函数和数据成员共享同一个名字.15) 内联函数inline function,内联函数不会引入任何函数调用。避免了调用函数比直接访问内存开销更大的类结构设置。在类中定义的成员函数会被自动当成是内联函数。既编译的时候会被扩展成直接访问字段。16) 函数重载function overloading,函数重载允许2个或以上的函数使用同一个名字,但是他们的参数表必须不同:参数类型不同,或参数数目不同。17) 静态成员,无论类的对象被定义了多少个,静态成员在对象中只有一个。这个是类的所以对象成员之间共享数据的一种方式.18) 域操作符class scope operator 双冒号。可以在类的外部定义一个成员函数属于它。19) 虚拟函数的调用要等到运行时刻,系统根据被调用对象的类型来决定选择虚拟函数的那一个实例。20) 虚拟函数比非虚拟函数的效率要低一些6因为它们不能被内联内联发生在编译时刻而虚拟函数是在运行时刻被处理的所以它们可能是运行时刻效率低下的原因之一。21) 类模板中的成员函数是在需要的时候才被实例化对应的类型的。22) 当访问名字空间下的方法的时候也会使用双冒号 MyNameSpace:MyClass,这个和类的外部方法符号一致的。23) namespace shortname=long_name_space_name使用简短名字或者使用using namespace name. 24) using namespace name:class可以使name名字空间仅仅class可见25) 字符串可以换行显示 在一行的末尾加上 反斜杠既可.26) 变量的rvalue右值存放的是read值,lvalue左值存放的是location值即是变量的内存地址值。27) 变量的定义会引起内存分配,一个对象分配后只能有一个去访问它的地址值,所以一个变量只能定义一次.28) 对象声明extern说明该对象在外部存在定义,这里是提供其类型说明,并不分配内存.可以一处定义多处声明,声明常放在头文件中,需要的时候被引用。也便于修改。29) 变量应该由3个值组成。变量的标识符:变量名字;变量的左值:内存地址值;变量的右值:存放的值.30) 命名规则:对象名一般用小写字母;31) 全局变量会自动给变量初始值,局部变量或new表达式生成的对象是未初始化的,他们的值是未定义的。32) 被声明了初始值的对象称做已经初始化的。33) 两个类型不同的指针禁止相互赋值,因为会引起编译器的解释困难。34) 空类型指针 void *可以接受除函数指针以外的其它数据类型的指针的赋值。35) 指针pr表示存储的对象的内存地址值,&pr表示的当前指针pr的内存地址值.36) 指针的加减法取决于指针的类型,类型决定了地址移动的单位长度.由于变量可能不是连续分配的,所以除了数组以外最好不要这么使用。37) c+提供2种类型的字符串,c保留下来的风格以及c+自己实现的string类.38) c风格的字符串在指针指向0和字符串为空串的时候长度都为0.39) Const变量必须在定义的时候初始化,const指针指向的对象不论是否是const变量都不能修改值。40) 引用由类型标识符加取地址符号组成,必须在定义的时候初始化,引用的对象一旦指定就不能再修改。指针类型不能直接赋值常量,引用类型只有在常变量类型的情况下才能赋值常量/ 仅对于const 引用才是合法的const int &ir = 1024;const int &ir2 = dval;.const double &dr = dval + 1.0;41) 引用对象之间的赋值修改的是引用指向的对象的值,而引用仍然指向原来的对象不会被修改。42) 指针不能指向引用43) 数组初始化的时候 长度必须确定 也不能是0 数组的长度要比字符串的长度多1个 因为末尾会有0占位.44) 枚举不仅定义了一个整数常量,还构成了一个集合。45) 如果变量不是常变量 即使赋值了也不能作为数组的维数.46) 数组不能被另外一个数组初始化,也不能赋值给另外个数组。另外c+不允许声明引用数组.47) C+中的vector ,complex, pair都支持泛型.48) C+ 内部定义的函数自动被声明成内联函数,但是在类外部实现的函数必须显示声明生内联函数。49) 在类体外定义/的内联成员函数应该被包含在含有该类定义的头文件中。50) 指针在解引用之前,需要判断下指针地址是否为0,否则报内存出错。51) 在逻辑与表达式中,只要第一个表达式的值为false,就不会计算第2个。在逻辑或表达式中,只要第一个表达式的值为true,就不会计算第2个。52) c/c+不保证从左到由的顺序,所以要注意运算顺序。53) c+ 栈 是后进先出 顺序放置数据 54) sizeof表达式在编译时刻计算,所以可以被看作常量表达式。55) 运行时刻的内存分配叫动态内存分配。56) 程序的空闲存储区叫堆heap.栈叫做stack.,栈是后进先出。57) 位操作符: 按位非:取反操作 1-0,0-1移位操作右移操作符 左边补0按位与& 有0就为0按位或| 有1就为1按位异或 1出现且1次 为1 其它的全部为058) c+ 整形值前面有个0表示八进制 0x表示十六进制59) 赋值操作符= 是右结合的 即使最先计算右边的。算术运算符是左结合的,左线计算左边的。60) 混合类型的算术表达式,最宽的类型为目标转换类型。61) Void*指针,常被叫做泛型指针。任何非const类型的指针都可以赋值给void*型的指针。指向对象类型未定或者对象类型可能发生变化的情况。Void*类型的指针再解引用之前必须进行类型转换,因为仅仅从void编译器无法知道对象的类型,从而无法计算对象的值。Void*指针赋值给其它指针的时候必须进行强制转换。62) Volatile 编译不会对改成员变量进行优化。63) Const_cast() 取消掉变量的常量性,static_cast用于将不确定的类型转换成确定的类型,具有较大的风险性,一般都需要进行检查。Reinterpret_cast()底层位操作转换。Danymic_cast支持在运行时刻来判断对象的类型。64) 程序语句中最简单的语句是空语句,由一个分号构成.65) Switch case分支语句,case某个分支可以有多条语句。但是如果有声明对象或变量的话必须加花括号把整个case分支包含起来。66) For循环可以应用在外部定义的变量,从而把初始化语句省略,只保留;号67) 标准c+之前的for循环的括号内的定义变量可以扩展外部。68) Do while 循环中,while不支持变量的定义和声明。69) Break只能放在循环语句和switch分值语句中,放在if语句中要报错。退出的时候是退出最近的那一层的for,while ,do while,switch循环或分支。70) Continue只能出现在循环语句中。71) Goto lablel, label 以:结束,如果右边紧挨右花括弧,需要加句空语句,即使加个;即可。Goto不能跳过有声明的语句,除非该语句被放在语句快中。尽量不用goto语句。72) 终止程序的办法。#include,abort();函数。 #include assert( 条件 );还有就是抛出异常。73) 链表中的元素不是顺序放在内存中的,所以对+指针不能找到下一个值。74) 抽象容器。顺序容器list,vector,deque(双端队列),由单一元素组成的顺序集合。关联容器,可以查询一个元素是否存在,并且可以有效的提取。如set,map.multimap.75) 容量是指下一次需要增长自己之前能够被加入到容器中的元素的总数。只指顺序容器,且不包括list.76) Vector适合小类型的数据使用,list适合复杂类型的使用。Vector的reserve()操作是调整容量,但是对于小类型的数据反而会变的更慢。大类型的数据效果会更好。List和set,map容器不支持排序?77) 如果容器的操作主要是在前段插入元素,应该选择deque而不是vector.78) 迭代器提供了一种一般化的方法,对关联容器或顺序容器的每个元素就行连续访问。79) Vector和deque在内存中是连续的,而list在内存中不是连续的。80) string函数 find(),find_first_of(),substr(),rfind(),find_first_not_of(),find_last_Of(), find_last_not_of(),erase(),assign(),append()81) vector a(“fdasfda”)为什么是错的 82) 当我们只想知道一个值是否存在时set 最有用处希望存储也可能修改一个相 关的值时map 最为有用.map has a alias name associative array.83) 有许多编译器不支持对vector,set,map等声明时的缺省参数,所以要手动加入allocator.默认情况下,关联容器用小于关系符排序。84) Map的count和find可以查找一个键值是否存在。关联容器不支持预定义的分配长度。必须插入而不是赋值。85) Multimap支持一个键多个项,但是multimap不支持下标操作符。86) 函数定义的地方参数叫做形式参数,当实际调用函数传递的参数叫实际参数。函数类型和内置数组类型不能作为函数的返回类型。标准c+中函数返回类型不能省略,以前的会默认当成int的返回类型。87) 引用指向了对象后就不能在去给引用变量赋值其它变量的名字,但是可以该量引用变量引用的对象的值。88) 为了支持class类型,尤其是有效直观的实现重载操作符机制,c+特别引入了引用类型.89) C+中的数组永远不会按值传递,参数默认的是数组的第0个值的指针,所以不会对数组的长度进程检查。当不想改变到数组的值,可以加const进行修饰.c风格的字符串是字符的数组,最后一个是0.90) 指向数组类型的指针变量,在取值的时候可以通过解引用和使用访问器来进行访问值。使用访问器的时候不需要再解引用。91) 函数调用的实参按位置解析,缺省参数只能用来替换函数调用缺少的尾部实参。函数申明可以全部或部分指定缺省参数实参。但是记住,在左边参数的任何缺省参数被提供之前,最右边的未初始化参数(在其他地方初始化的可以不提供了)必须提供缺省参数值。一参数只能在一个文件中被指定一次缺省参数。92) Inline函数必须同调用它的函数在同一个文本中出现。Inline函数对编译器来说只是个建议,可能会被忽略,因为有的时候不适合展开函数。93) 链接指示符用于申明其它语言写的函数,不能在函数内部声明。复合申明即申明多个函数可以在外部加好括号,当放include的时候是将该文件的所有函数申明了。94) 函数指针与指针函数。函数的类型只决定于返回值类型与参数表。函数的类型决定了指针类型的不一致。当一个函数没有调用操作符类型的时候,会被解释成指向该类型的函数指针。函数指针赋值为0的时候,表示不指向任何指针。函数指针调用前确保已经被初始化或赋值,切不指向0.95) 函数指针数组,每个数组的元素都是一个指向函数的函数指针。96) 注意到,多维数组的指针表达方式和通过typedef定义的指向函数的指针数组定义方式很像。97) 函数指针定义的时候,返回的类型是对应的前面的符号的类型,如int (*function) ( int parameter).而返回指针函数的定义如下:int(*function(int a)(int parameter).这种形式的算不算是指针函数?98) 函数参数的类型不能是函数类型,函数类型的将会杯转换成对应的函数指针类型。函数指针可以用作参数和返回类型。函数不能返回函数类型,可以返回指向它的函数指针。函数指针调用时,可以直接想调用函数一样输入名字再加参数,或者先加括号解除引用再调用。99) 指向c+的函数指针和指向c的函数指针类型不一样.不能相互赋值。当然部分编译器已经把这个作为一种扩展而不加限制。100) 链接指示符extern “”当声明一个函数时,这个函数的参数也会被当作链接指示的类型的函数。101) c+中有三种域,类域、命名空间域、局部域。If语句在条件中定义的变量可以在其分支语句中有效。102) 全局域内引入的变量叫全局变量,全局变量是一个运行时刻实体,生命期从程序开始始,程序结束终。103) 函数声明指定了函数的名字、返回类型及其参数表。函数定义除了函数声明还包括函数体。104) 对象的声明即使定义的表达式,但是定义只能出现一次,所以加上了extern关键字,既是不会分配内存。但是记得不能赋值。否则仍然被看成是定义。105) 类型安全链接是用于检查在声明时候函数的参数不一致的情况。106) 符号常量和inline函数可以被定义多次,所以可以放在头文件里面。107) 建议把那些天生无法内联的函数不声明为inline,并且不放在头文件中。108) C+中的local object分3种,automatic object(自动对象),register object(寄存器对象),local static object(局部静态对象)。自动对象随函数的调用而分配内存在栈上,随函数的结束而结束,它的任何值都被丢掉。所以它的地址不应该作为函数的返回值,因为是一个无效无值的存储区。109) 空悬指针(dangling pointer),存放有生命期长于它的自动变量的地址的指针。110) 在函数中被频繁使用的自动变量可以使用register关键字。有的编译器会把它加载到记起的寄存器中。但这个对编译器来说只是个建议。111) 未初始化的局部静态对象会初始化为0,自动对象的值可能回事任意值,除非它被显示初始化。112) 动态分配的对象.dynamically allocated object,动态分配的对象被分配在程序的空闲存储区里面,分配的数组长度可以在运行时刻计算。113) 再对指针delete之前没有必要进行测试是否指针的值为0,因为系统默认delete操作就自动测试。Delete对象之后,最好把指针设为0,避免让指针变成空悬指针。Delete操作只能应用在用new表达式生成的对象上。114) 动态分配容易照成的3种错误。1.delete表达式失败,内存无法返回,照成内存泄漏;2.多个指针引用到同一个地址,不同指针执行了不同的操作。3.delete指针的对象没有被置为0,然后继续读写指针指向的对象。115) Auto_ptr可以帮助程序员自动管理用new动态分配的单个对象,不支持数组,auto_ptr指针生命期结束的时候,对象被自动释放。Get()用于判断值auto_ptr指针值是否为0.在auto_ptr被定义之后,不能直接赋值,只能通过reset(new表达式)来完成。Auto_Ptr在指向新值之前会删除以前的变量。用assign(“值”)可以不删除原来的对象,仅仅是修改它的值。Release()是取的指针的地址值,并且删除以前的那个指针。保证始终只有一个auto_ptr指向一个对象。116) Auto_ptr的get()和release()区别。前者,把指针地址赋值给其它变量,并不交出控制权,后者要交出控制权。在做delete操作的时候,对于前者要作用在它本身,后面要作用在被赋值的新的指针对象上。117) 空闲内存区动态分配的数组必须在for循环中初始化。因为大多数处理C 风格字符串数组的例程都要遍历数组直到结尾空字符缺少该空字符常常导致严重的程序错误因为程序会读写到其他不该读写的内存我们建议使用C+标准库string 这正是避免此类错误的一个原因.118) 对于由new表达式分配的内存,只有第一维可以是运行时刻的常量,其它维必须是在编译时刻已知的常量值。119) 当在函数内部要访问外部的同名参数时候,可以使用:变量名 的方式得到。120) 成员的定义必须在其声明所在的名字空间和其外围名字空间定义。121) 在某个文件中使用没有命名的名字空间,可以使该名字空间的函数仅仅在这个文件内部可见。使用这个函数的时候,直接调用名字即可。C中实现这个办法是将变量定义成静态的,这样在其它文件中就不可见。122) Namespace short_name=ture_long_name可以使用shortname来代替长的名字空间。Using 名字空间:函数 可以部分引用名字空间的内容。Using namespace 名字 引入整个名字空间。由using引起的二义性错误是在该名字被使用时才被检测到的。Using引入的变量会被看成是一种全局声明,所以局部变量可以隐藏using引入的变量。由多个using 指示符引起的二义性错误只能在使用点上被检测到。123) 只有参数和返回类型都不同才叫做函数的重载,反之2个都不同的时候会被看成是函数的重复声明。只有缺省实参不同也会被看成是函数的重复声明。当函数的参数是按值传递的时候,参数前有const或volatile都被看成是同一个函数或声明。当是按指针或引用传递的时候就会被看成是不同的函数。124) 重载函数的声明都必须在同一个域中,一个声明为局部的函数将隐藏而不是重载一个全剧域中声明的函数。不同名字空间,不同类的成员函数都不可以重载。但是通过using指示符,可以将不同名字空间的函数在当前引入域进行函数重载。125) Using声明和using 指示符。前者是引入名字空间的字段或函数,后者是引入整个名字空间。126) 链接指示符只能指定重载函数中的一个函数,因为编译器没有办法对这种外部函数进行特殊编码,函数调用的时候会存在多个名字的函数而导致编译链接不能保证正确安全进行。两个函数指针类型之间不能进行类型转换。127) 函数重载解析是把函数调用与重载函数集合中的一个函数相关联的过程。候选函数-可行函数-最佳可行函数。最佳可行函数选择过程中有个优先级的规则。精确匹配好于提升转换,提升转换好于标准转换,标准转换好于用户自定义转换。128) 从一个左值表达式中抽取值的过程就叫做左值向右值的转换。左值转右值算是精确匹配。129) 所有的标准转换都被视为是等价的。所以当有2个函数要求匹配他们的参数的时候,就会产生二义性,编译器将标记为错误。130) 枚举不能作为int*空指针的转换,即使枚举值为0。131) 当引用作为实参类型的时候,传递的是左值,类型是引用的对象的类型。132) 函数的形参是引用类型,这个类型不同于实参的类型,而实参不是引用类型的时候就会报错。因为类型转换产生的是一个临时值,而临时值不能const类型的,所以不能初始化该引用。133) 临时值不能初始化非const类型的引用。如果引用前面加了const就可以了。134) 简而言之对于引用参数来说如果实参是该引用的有效初始值则该实参是精确匹配如果该实参不是引用的有效初始值则不匹配。135) 函数重载解析:136) 候选函数:1函数的声明在候选点上可见;2函数实参的类型是在一个名字空间被声明的,则该名字空间中与被调用函数同名的函数也被加入到候选函数中来。3.嵌套域中的声明函数隐藏而不是重载了外围域中的函数,这个时候调用点上选择的是嵌套域中的函数。4.使用using声明的时候,会覆盖掉全局域中的同名函数,减少可选函数。但使用using指示符的时候,不论是放在函数内部还是全局域中都不会覆盖同名函数。137) 可选函数:可行函数是这样的函数对于每个实参都存在到函数参数表中相应的参数类型之间的转换。138) 在函数模板内部定义声明中的对象或类型不能与模板参数同名。全局变量名会被同名的模板参数覆盖。139) 模板函数当有多个参数的时候,关键字class或typename不能省略。140) 函数模板也可以声明为inline或extern 但必须放在template标签之后。141) 模板实参推演,由函数实参的类型来决定模板实参的类型和值的过程。142) 模板函数在调用的时候可以通过显示指定类型或通过判断实参类型来实例化。143) 由于编译器的强悍功能,所以尽可能的不要用显示模板实参。144) 我们通过在模板定义中的关键字template 之前加上关键字export 来声明一个可导出的函数模板当函数模板被导出时我们就可以在任意程序文本文件中使用模板的实例而我们所需要做的就是在使用之前声明该模板,比如引入其声明头文件。有的编译器可能不需要这样,但是标准c+要求这样去做。145) C+模板编译模式包含2种,包含模式和分离编译模式。包含模式就是模板函数的声明即是定义在一个头文件中。而分离编译模式声明在一个头文件中,实现在另外一个文本中,用关键字export来标明并实现。146) 在显示实例化声明中,函数模板的定义必须被给出。如果该定义不可见,则该显示实例化声明是错误的。147) 模板显示特化定义是指为函数模板实例化提供特别的定义。其实就是在函数模板实例化的情况下在前面加上template。148) 函数模板显示特化的作用?与普通函数的区别,理论上没有区别,但是模板的特化是非常有用的。它是一个在编译期的条件判断。当编译器在编译时找到了符合的特化实现,就会使用这个特化实现。这就叫编译器多态(或者叫静态多态)。这种东西对编写基础库是很有用的。这也就是为何c+的基础库大量使用了模板技术,而且大量使用了特化,特别是偏特化。特化主要用于类模板,由于一个类模板上拥有或多或少的函数模板,这些模板不一定符合特殊场合的使用,这使用用全局特化或者偏特化的方式可以修改一点地方而不需要重写这个类,有些资料也显示普通函数的重载采用的最优匹配方式比特化要来得完美,性能也高一点,但是在类模板上可以大大的提高扩展特性,现在许多库就是通过这种方式适应不同场合的使用的。其实感觉就是直接调用函数时候,编译器很难根据实参去实例化模板函数。所以手动来特化有利于编译器编译的速度。有了显示特化,函数模板不会在生成函数模板实例。149) 注意在选择候选函数的时候,首先是对模板函数进行实参推演。如果没有合适的候选函数,即使有特化的函数模板的实例适合也不能进入候选函数。150) 实现了模板函数,往往还要加入一个它的实例化的普通函数。因为当有的函数的实参在调用的时候,由于模板函数实参推演失败会导致没有候选函数,这个时候普通函数却可以通过标准转换等来完成。即保证了一定有候选函数。151) 函数模板中的子函数调用的时候。如果与模板参数无关,则名字解析是在函数模板定义的时候解析的。如果是有关的话,则是在函数模板实例化的时候解析的。152) 当一个函数被声明成为friend。他就可以引用类的私有数据成员。153) 异常处理是一种允许两个独立开发的程序组件在程序执行期间遇到程序不正常的情况称为异常exception 时相互通信的机制。154) Try引入一个局部域,在try中声明的变量在其它地方不可以引用即使在catch中。155) 使用引用类型的异常声明catch 子句能够修改异常对象但是由throw 表达式指定的任何变量仍都不受影响。引用只能修改到throw表达式创建的异常对象,如果不是创建的比如全局变量就仍然不受影响。注意catch中如果再抛出throw异常,要注意catch()中的对象是否是引用,如果是引用就抛出它自己。或者就抛出的是try中的异常抛出的对象。156) Catch all:catch()可以捕获任何类型的异常,当它与catch并列存在的时候一定要放最后一个,或者要报错。其它的catch按捕获顺序来,如果获得一个就不执行其它的catch了。157) 异常规范exception specification 提供了一种方案它能够随着函数声明列出该函数可能抛出的异常它保证该函数不会抛出任何其他类型的异常。异常声明是函数接口的一部分,它必须在头文件的函数声明上指定。不同地方的同一个函数声明必须带上异常规范,如果其中一个有。切不能累加。当抛出了不能被识别的异常时候,会调用在编译的时候就设置好的unexpected function,默认会去调用terminate()退出。空的异常规范保证函数不会抛出任何异常。如果函数没有指定异常规范意味着该函数可以抛出任何类型的异常。158) 函数指针作为参数被引用的时候不能被内联,影响效率。所以出现了函数对象。函数对象是一个类它重载了函数调用操作符operator() 该操作符封装了通常应该被实现为一个函数的动作典型情况下函数对象被作为实参传递给泛型算法当然我们也可以定义独立的函数对象。159) 函数适配器用于指定函数对像的单个参数或者取反操作。改变默认必须是2元关系的函数对象。Binder和negator。参考c+ primer third version 泛型算法12.3.5。160) C+语言要求绑定在const vector 上的iterator 也必须是const iterator。const 容器只能被绑定在const iterator 上这样的要求与const 指针只能指向const 数组的行为一样在两种情况下C+语言都努力保证const 容器的内容不会被改变。161) 关联容器map和set在内部维护元素的排序顺序,一边快速查找和获取。因为不允许在上面应用重新排序的泛型算法。如果要排序必须先将他们拷贝到顺序容器vector或list中。162) List是双向链表,它保存有指向上和下一个链表元素的链成员。可以把元素插入到list的任意位置上或删除,但是不能随机访问。不是连续的分配内存。163) 除了静态成员以外的类的数据成员不能在类体中被显示初始化。164) 只有当一个类的类体完整的时候,它才被视为已经定义。所以一个类不能有自身类型的数据成员。但当一个类的类头被看到的时候,就已经声明了,所以可以把自身类型的指针或引用作为数据成员。165) 虽然每个类对象都有自己的类数据成员拷贝但是每个类成员函数的拷贝只有一份.他们是靠this指针来区分这不同的对象的数据的。166) 类的成员函数如果声明成常类型的话,放在参数表和函数体之间。任何修改类数据成员的函数都不能被声明为const。但是如果声明了可以修改类的指针成员指向的对象的值。const 成员函数可以被相同参数表的非const 成员函数重载例,调用时候根据类是不是定义为const来匹配函数。一个const 类对象从构造完成时刻到析构开始时刻这段时间内被认为是const。167) 当把一个类的数据成员声明成为mutable的时候。它永远都不会是const,可以随意修改。168) This指针。每个类成员函数都含有一个指向被调用对象的指针这个指针被称为this。一般情况不需要显示引用this指针。在类的成员函数中返回自己 return *this。169) 点操作符和箭头操作符是左结合的。170) 静态成员和非静态的比较。静态成员的类型可以是其所属类的对象,而份非静态只能是该类的对像的指针或引用。静态数据成员可以作为类成员函数的实参,而非static成员不能。171) 静态成员函数不能声明为const或valatile,不能在类的外部声明,没有this指针,所以不能类的非静态数据成员。172) 一般的函数指针不能赋值为类的成员函数,因为缺少this指针。173) 成员数据指针的格式 : type classname:* point_name=&classname:member_data174) 成员函数指针的格式 : return_Type (Class_Name:*Function_Point_Name)()=&Class_Name:Member_Function_Name175) 静态数据成员指针不需要指定类名,和普通指针一样。176) Union类,union类的数据成员可以是private或public。Union类不能有静态数据成员或是引用成员。不能有带有构造函数或析构函数或拷贝赋值操作符的类作为成员类型。Union中的数据成员的存储开始位置都一样,任意的赋值都会覆盖以前的数据,其存储区的大小取决于最大的成员的类型。读取的时候只可以访问被赋值的那个变量。177) 匿名union的数据成员可以在定义匿名union的域中被直接访问。178) Union是一种节省空间的类,bit_field是一种节省空间的成员。179) &操作符不能应用在位域上,没有指向位域的指针,位域也不能使类的静态成员。180) 在类定义中用到的名字必须在使用前被声明,但是有2种例外。一种是内联函数的函数体中,第二种是被用作缺省实参的名字,但是该数据成员必须是static的。181) 在类外部定义在内部通过typedef声明的数据成员的时候必须在该数据成员前面也加类:。182) 嵌套类之间不能相互访问对方的私有数据成员。除非被对方声明为友元类。Friend class class_name.183) 嵌套类的数据成员含私有数据成员可以在外部被定义。嵌套类可以在外部定义,但是必须在父类中声明。注意,嵌套类的外部定义和类的继承格式很像。184) 定义在类外部的子嵌套类不能访问父类的非静态成员,必须通过类对象的引用或指针。见c+ primer,page 556。185) 在嵌套域的内部可以直接访问public类型的静态成员,枚举值,类型名。其中类型名包括:typedef名字,枚举类型名字,类名字。但是在外部的时候必须加类名字空间,枚举值可以不用。因为枚举类型没有像类一样维护自己的类域。186) 被定义在函数体内的类,叫做局部类。不能被外部的变量访问,所以也没有静态成员。187) 当类是有默认构造函数初始化的时候,一般认为是没有被初始化。188) 显示初始表初始化类的时候,它的所有数据成员必须是公有的。189) 类的构造函数不能指定返回类型,也不能指定void类型。190) 类的构造函数不能被const和volatile修饰。191) Explicit关键字只能用来修饰构造函数,切提醒构造函数不要提供隐式转换。192) 不是每个类都必须要析构函数。如果类成员都是值类型的成员则不需要析构函数。193) 只有当delete表达式的指针指向一个带有析构函数的类时,编译器才会调用析构函数。194) 类的数据成员,const类型或引用类型的时候必须在成员初始化表中完成。因为这2个在构造函数开始的时候必须已经初始化完成。其它类型的数据成员在构造函数或成员初始化表中都无影响。195) 初始化的顺序是按照类的成员定义的顺序来进行的,和初始化表中的变量顺序没有关系。但是初始化表中的最迟一个都早于构造函数内部的第一个。成员之间的赋值最好是放在构造函数内部。196) 一般最好是在成员初始化表中初始化类的所有类对象。197) c+重大的一个缺陷就是不能有效的返回类对象,即是不能返回局部对象的引用或指针。其解决办法是使用了返回值语言扩展技术,说白了就是把结果作为一个引用变量传入进去。198) 函数重载的时候,const关键字放最后面,但是要放花括号之前。199) 只有左操作数是类类型的时候才会考虑类的重载函数。200) 操作符重载时,类成员和名字空间成员的选择。操作符的左操作数不是类对象类型的时候,必须用名字空间成员。即是2个参数。C+要求,=,(),-操作符必须被定义为类操作符。201) 程序员只能为类类型或枚举类型的操作数定义重载操作符202) 操作符预定义的操作数个数arity 必须被保留例如一元的逻辑非操作符不能被定义为针对两个String 对象的二元操作符. 四个预定义的操作符+ - * 和& 既可被用作一元操作符也可被用作二元操作符.除了operator()以外,其它操作符提供默认实参是非法的。203) 友元声明以关键字friend 开始它只能出现在类定义中因为友元不是授权类的成员所以它不受其所在类的声明区域public private 和protected 的影响这里我们选择把所有友元声明组织在一起并放在类头之后。204) 一个类必须把它希望与之建立友元关系的重载函数集中的每个函数都声明为友元, 如果一个函数操纵两个不同类类型的对象而且该函数需要访问这两个类的非公有成员则这个函数可以被声明为这两个类的友元或者作为一个类的成员函数并声明为另一个类的友元。205) 只有当一个类的定义已经被看到时它的成员函数才能被声明为另一个类的友元。如果2个类需要相互把对方的成员函数作为自己的一个友元,那么可以把类直接声明成为友元。206) C+默认内置数据类型都是有符号的,所以最左边的那位都会被当作符号位,仅仅用来标识正负关系。207) 机器字表示机器一次性处理的长度,比如32位机就表达一次性处理32BIT,即是3个机器字节。在32位机子中:Char占用一个机器字节。Short半个机器字(2字节),int占用一个机器字(4字节),long和int长度一样,但是其它机器中,long是2个机器字。Float单精度1个机器字,double双精度2个机器字,long double三或四个机器字。以u结尾的表示无符号,以L结尾的int表示长整形,以L结尾的浮点型表示扩展精度。以f 结尾的表示单精度,以e结尾的表示双精度。默认是十进制,前面加0表示8进制,前面加0X表示十六进制。Unsigned int,表示无符号整型.signed int表示有符号整型。208) 转换函数是一种特殊类型的类的成员函数。他把一种类型转换成另外一种类型。;格式是operator 类型().不能指定返回类型和参数表。209) 如果需要编译器会在调用构造函数执行用户定义的转换之前在实参上应用标准转换序列。210) 如果实参是一个类类型的对象类类型的指针类类型的引用或者指向类成员的指针并且该类类型是在一个用户声明的名字空间中被声明的则在该名字空间中声明的与函数调用同名的函数也被加入到候选函数集中;如果实参是一个类类型的对象类类型的指针类类型的引用或者指向类成员的指针并且该类有与函数调用同名的友元friend 函数则该友元函数被加入到候选函数集中。211) 如果一个函数调用的实参是一个类类型的对象类类型的指针类类型的引用或者是指向类成员的指针则候选函数是以下各个函数集合的并集在调用点可见的函数在定义该类的名字空间中声明的函数以及在类成员表中声明为友元的函数。212) 调用点可见的候选函数集只包含名字解析成功的域中声明的函数。即使外部域中有可用函数,也不作为候选函数。前面的函数如果都不是可选函数,那么编译会提示出错。213) 标准转换序列总是好于用户定义的转换序列, 用户定义的转换序列中只能有一个用户定义的转换所以在第一个用户定义的转换之后只能考虑标准转换。如果两个用户定义的转换序列使用了相同的转换函数则转换函数后面的标准转换的等级被作为选择最佳用户定义转换序列的依据。因为两个用户定义的转换序列使用了不同的转换函数所以不能判定哪个函数对该调用有最佳的参数类型标准转换序列的等级也不能被用来判定最佳转换序列以及最佳参数类型所以该调用被编译器标记为二义的。214) 重载解析与成员函数。不像名字空间函数成员函数在类成员表中只能被声明一次。215) Const与函数重载解析。Const对象只能调用const非静态函数。静态成员函数从不会因为被调对象或指针的限定修饰符const 或volatile而被排除在可行函数集之外静态成员函数被认为匹配它所在类类型的任何对象或指针。216) 类模板被视为一个链表。Typename是在标准c+中才引入的,为了帮助编译器区分参数到底是类还是类型变量。标准c+之前的模板参数不支持缺省实参。217) 模板定义和定义都可以引用类的模板或类模板的实例,但是在模板定义的上下文环境之外,只能使用类模板实例。218) 标准c+中,声明一个类模板实例的指针或引用不会导致模板被实例化;定义一个类时需要知道该类的定义。因为编译器需要知道其大小以便为其分配内存。另外,只有就是在解引用或调用数据成员、成员函数的时候才能实例化类模板。219) 类模板的参数如果是非类型的参数,那它的类型必须是常量表达式、const对象的值,名字空间中对象的地址、对象的大小。而new表达式,非const变量的值都不能作为参数。220) 类模板实例化的时候,类型参数和非类型参数之间可以进行转换。但是必须是下面的这些情况。(1)左值转换:左值到右值的转换,数组到指针的转换,函数到指针的转换;(2)限定修饰符转换:从指针类型到常指针类型的转换;(3)提升:从长度小的到长度大的类型;(4)整型之间的转换221) 0不能通过隐式转换成指针,可以通过static_cast来显式完成。222) 类模板的成员函数本身也是一个模板。标准c+要求这样的成员函数只有在被调用或者取地址的时候才被实例化。223) 类模板中可以使用的友元声明。(1) 非模板友元类或友元函数,一个类的成员在被声明成为类的友元之前必须让其类已经被定义;(2)绑定的友元类模板或函数模板,1对1的关系;(3)非绑定的友元类模板或函数模板,1对多的关系,标准c+才支持这种。注意第二种方法,类部申明友元的时候,在函数的名字后面和小括号的前面必须加。224) 注意第222条款,使用方法2必须在最顶部声明类和友元函数的名字,因为他们在交叉使用容易出错。当使用operator的友元函数要注意在后面还要加.使用方法3仅仅需要注意2个模板参数的名字不能一样。225) 类模板声明为友元有2种情况:1是将类模板的虽有实例化对象都声明为当前类模板的友元,2是只声明指定类型的类模板为当前的友元。226) 类的友元函数不属于类,所以不能用public,private,protected等来修饰。如果有这些修饰符存在。那么应该放在他们的外边。227) 类模板的静态数据成员。只有当程序使用静态数据成员时它才会从模板定义中被真正实例化类模板的静态成员本身就是一个模板静态数据成员的模板定义不会引起任何内存被分配只有对静态数据成员的某个特定的实例才会分配内存每个静态数据成员实例都与一个类模板实例相对应因此一个静态数据成员的实例在被引用的时候总是要通过一个特定的类模板实例。228) 类模板与嵌套类,嵌套类不会在父类实例化的时候就实例化。除非是被解引用等操作。标准c+中,类模板支持函数模板和类模板作为自己的一个元素。229) 如果一个成员模板被定义在类模板定义之外则在它的定义前面就必须加上类模板参数表然后再跟上它自己的模板参数表. 模板参数不一定与类模板定义中指定的名字相同.230) C+模板编译模式.(1) 包含编译模式:成员函数和静态成员的定义必须被包含在和类模板的至少同一个文件中。 (2) 分离编译模式:类模板定义和其inline成员函数定义都被放在头文件中,而非inline成员函数和静态数据成员被放在程序文本中。但是这个类模板必须定义为export,其静态数据和成员函数也可以声明为export,但是在程序中只能被声明一次。231) 显示实例化类模板 template class Name,它的所有成员也都会被实例化,所以这个时候需要类提供所有成员的定义。232) 类模板部分特化,在类名字后面加了。并在里面指定了部分实参。当存在类模板部分特化的时候,会优先调用这个模板。但是必须为其提供构造函数。233) 类模板中的名字解析。234) 多台是指基类的指针或引用操纵多个类型(基类的派生类)的能力。235) 动态绑定是在运行时刻解析出需要被调用的函数。C+实现这种机制的原理是使用了一种虚拟函数。缺省情况下,函数是在编译时刻静态解析。236

温馨提示

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

评论

0/150

提交评论