Onway

我是一只菜菜菜菜鸟...
posts - 61, comments - 56, trackbacks - 0, articles - 34

《C++ Primer 中文版》笔记

Posted on 2011-12-04 14:12 Onway 阅读(701) 评论(0)  编辑 收藏 引用 所属分类: 使用说明

变量

  1. 可以通过extern关键字声明变量而不定义它。

  2. 如果声明有初始化式,那么它被当做是定义。

  3. 只有当extern声明位于函数外部时,才可以含有初始化式。

函数

  1. 带默认参数的函数,声明与定义谁在前谁给出默认值。

  2. 如果局部地声明一个同名函数,则该函数将屏蔽而不是重载在外层作用域声明的同名函数。

指针

1)int a[3][4];a==&a[0];a[0]==&a[0][0];

  1. a[0]==*(a+0) *(a[0]+1)==*(*(a+0)+1)==a[0][1];

  2. 在二维数组中,a[0]不是值,是地址。

  3. a[i][j]==*(*(a+i)+j);

名字作用域

1)用来区分名字的不同意义的上下文称为作用域。名字的作用域指的是知道该名字的程序文本区。

2)一个名称可以和不同作用域的不同实体相关联。

3)定义在所有函数外部的名字具有全局作用域。

4)定义在函数内部的名字具有局部作用域。

  1. 定义在语句中的名字具有局域作用域。

  2. 可以将一个非const变量定义在一个文件中,在另外的文件中,只要做了合适的声明,就可以使用该变量。

7)在全局作用域声明的const变量是定义该对象的文件的局部变量。

8)非const变量默认为extern,要使const变量能够在其他的文件中访问,必须显式指定为extern.

Const对象

1)const变量默认是文件的局部变量。

2)在头文件定义const变量,任何包含该头文件的源文件都不会出现重定义的情况,原因是const变量默认是文件作用域。这样出现的结果是每个源文件都定义了自己的const变量。

4)由于编译时的替换,在运行时不会有任何存储空间存储常量表达式初始化的const变量。

5)如果const变量不是用常量表达式初始化,那么它就不应该在头文件定义。相反,和其他的变量一样,该const变量应在源文件定义并初始化。应在头文件为它添加extern声明,以别其他文件共享。

6)2010-11-3(下午,const引用)

  1. 引用不能改变指向,且必须初始化才能使用

  2. const引用与指向const的引用是同一个意思

  3. 非const引用不能指向const对象。

  4. const引用可以指向非const对象。

  5. const引用可以指向相关类型或是右值。

  6. const引用只能读取,不能通过const引用改变其所指向对象的值。

预处理器

1)#include设施是C++预处理器的一部分。

2)预处理器处理程序源码在编译器之前运行。

3)设计头文件是,我们必须保证多次包含同一头文件不会引起该头文件定义的类和对象被多次定义。

4)预处理器允许我们自定义变量,预处理器变量的名字在程序中必须是唯一的。任何与预处理器变量相匹配的名字的使用都关联到该预处理器变量。

5)预处理器变量有两种状态:已定义和未定义。定义预处理器变量和检测器状态所用的预处理器指示不同。

6)头文件应该含有保护符,即使这些头文件不会被其他头文件包含。编写头文件保护符不难,而且如果头文件被包含多次,它可以避免难以理解的编译错误。

头文件

  1. 头文件一般包含类的定义,extern变量的声明和函数的声明。

  2. 因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。

  3. 对于头文件不应该含有定义这一规则,有三个例外。头文件可以定义类,值在编译时就已知的const对象和inline函数。这些实体可在多个源文件中定义,只要每个源文件中的定义是相同的。

  4. 类,const对象,inline函数是具有文件作用域。

  5. typedef不是定义也不是声明,是一个编译前的预处理。具有文件作用域。

2010-10-14

  1. 标准库定义了四个IO对象,分别是cin,cout,cerr,clog.

  2. c++成对注释是从C继承过来的。

  3. wchar_t是内置类型,用于扩展字符集,比如汉字和日语,这些字符集中的一些字符不能用单个char表示。

  4. 转义字符没有十进制数字形式,\ooo表示八进制表示转义,\xooo表示十六进制表示。

  5. 操作符的替代名用于支持某些不支持标准C++操作符集的字符集,不能用作变量标识符。

  6. 标识符不能包含两个连续下划线,不能下划线开头紧跟一个大写字母,在函数外定义的标识符不能以下划线开头。

  7. 定义用于分配空间,指定初始值;定义包含了声明;extern用于声明。


2010-10-16

  1. 标准库类型不允许做复制或是赋值操作

    1. 只有支持复制的元素类型才可以存储在vector或其他容器类型里。

    2. 形参或返回类型不能为流类型。如需传递或返回IO对象,则必须使用指针或引用。

  1. 如果一个流调用tie函数将其本身绑在传递给tie的ostream实参对象上,则该流上的任何IO操作都会刷新实参所关联的缓冲区。如果在调用tie函数时传递实参“0”,则打破改流上已存在的捆绑。

  2. 由于历史原因,IO标准库使用C风格字符串,而不是C++ string类型作为文件名。

  3. 对于用ofstream打开的文件,要保存文件中已存在的数据,唯一的方法是显示指定app模式打开。

  4. string类型转C风格字符串用c_str成员函数。

  5. 逗号操作符的求解过程:首先计算它的每一个操作数,然后返回最右边操作数作为整个操作的结果。

  6. 每个IO对象管理一个缓冲区,用于存储程序读写的数据。

  7. 要使用标准库定义的字符串流,必须包含头文件sstream。


2010-10-23 (第九章,容器和算法)

  1. 这些容器类型的差别在于他们提供哪些操作,但是如果两个容器提供了相同的操作,则他们的接口(函数名字和参数个数)应该相同。

  2. 所有的容器都是类模板。所有的容器类型都定义了默认构造函数,由于创建指定的容器对象。

  3. 不提供元素初始化式时,标准库将为该容器实现值初始化。采用这种类型的初始化,元素类型必须是内置或复合类型,或者是提供了默认构造函数的类类型。如果元素类型没有默认构造函数,则必须显示指定其元素初始化式。

  4. 容器元素类型必须满足以下两个(最低限度的)约束:

a,元素类型必须支持赋值运算。

b,元素类型的对象必须可以复制。

  1. 除了引用类型外,所有内置或是复合类型都可以用做元素类型。引用不支持一般意义的赋值运算,因此没有元素是引用类型的容器。

  2. 除输入输出标准库类型之外,所有其他标准库类型都是有效地容器元素类型。特别地,容器本身也满足上述要求,因此,可以定义元素本身就是容器类型的容器。

  3. 此外,一些容器操作对元素类型还有特殊要求。如果元素类型不支持这些特殊要求,则相关的容器操作就不能执行:我们可以定义该类型的容器,单不能使用某些特定的操作。

  4. 其中一种需外加类型要求的容器操作是指定容器大小并提供单个初始化式的构造函数。如果容器存储类类型的对象,那么只有当其元素类型提供默认构造函数时,容器才能使用这种构造函数。

  5. 在指定容器元素为容器类型时,必须如下(两个同向尖括号之间)使用空格。

  6. 每种容器类型都提供若干共同工作的迭代器类型。与容器类型一样,所有迭代器具有相同的接口:如果某种迭代器支持某种操作,那么支持这种操作的其他迭代器也会以相同的方式支持这种操作。

  7. 无法检查迭代器是否有效,也无法通过测试来发现迭代器是否已经失效。任何无效迭代器的使用都可能导致运行时错误,单程序不一定崩溃,否则检查这种错误也许会容易些。

  8. 简单地说,逆序迭代器从后向前遍历容器,并反转了某些相关的迭代器操作:例如,在逆序迭代器上做++运算将指向容器中的前一个元素。

  9. 所有的容器类型都支持用关系操作符来实现两个容器的比较。

  10. 容器的比较是基于容器内元素的比较,容器的比较使用了元素类型定义的同一个关系操作符……。


2010-10-24早 (续上)

  1. 对于所有的容器类型,如果resize操作压缩了容器,则指向已删除的元素的迭代器失效。

  2. 使用下标运算的另一个可选方案是at成员函数。这个函数的行为和下标运算相似,但是如果给出的下标无效,at函数将会抛出out_of_range异常。

  3. 与赋值相关的操作符都作用于整个容器。……赋值后,左右两边的容器相等:尽管赋值前两个容器的长度可能不相等,但赋值后两个容器都具有右操作数的长度。

  4. 完成swap操作后,尽管被交换的元素已经存放在另一容器中,但迭代器仍然指向相同的元素。

  5. 如果在不同(或相同)类型的容器内,元素类型不相同但是互相兼容,则其赋值运算必须使用assign函数。

  6. 带有一对迭代器参数的assign操作允许我们将一个容器的元素赋给另一个不同类型的容器。

  7. swap操作实现交换两个容器内所有元素的功能。要交换的容器的类型必须匹配:操作数必须是相同类型的容器,而且所存储的元素类型也必须相同。

  8. capacity操作获取在容器需要分配更多的存储空间之前能够存储的元素总数,而reserve操作则告诉vector容器应该预留多少个元素的存储空间。

  9. 每当vector容器不得不分配新额存储空间时,以加倍当前容量的分配策略实现重新分配。

  10. 元素是否连续存储还会显著地影响:

a,在容器的中间位置添加或删除元素的代价

b,执行容器元素的随机访问的代价

  1. 通常来说,除非找到选择使用其他容器的更好理由,否则vector容器都是最佳选择。

  2. 本质上,适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同德抽象类型的工作方式实现。

  3. 所有容器适配器都根据其基础容器类型所支持的操作来定义自己的操作。


2010-10-31下午(第十章 关联容器)

  1. 关联容器和顺序容器的本质区别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器的位置顺序存储和访问元素。

  2. set和map类型的对象所包含的元素都具有不同的键,不允许为同一个键添加第二个元素。

  3. 如果在创建pair对象时不提供初始化式,则调用默认构造函数对其成员采用值初始化。

  4. 在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数。……所用的比较函数必须在建类型上定义严格弱排序。……对于两个键,如果它们互相之间都不存在“小于”关系,则容器将之视为相同的键。

  5. 在学习map的接口时,需谨记value_type是pair类型,它的值成员可以修改,但键成员不能修改。

  6. 用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。

  7. map迭代器返回value_type类型的值——包含const key_type和mapped_type类型成员的pair对象;下标操作则返回一个mapped_type类型的值。

  8. 插入单个元素的insert版本使用键值pair类型的参数。类似的,对于参数为一对迭代器的版本,迭代器必须指向键值pair类型的元素。

  9. 如果试图插入的元素所对应的键已在容器中,则inset将不再做任何操作。

  10. 使用下标存在一个很危险的副作用:如果该键不再map容器中,那么下标操作会插入一个具有该键的新元素。

  11. 当然,在执行count后再适用下标操作,实际上是对元素作了两次查找。如果希望当元素存在时就使用它,则应该用find操作。

  12. 当只想知道一个值是否存在时,使用set容器是最适合的。

  13. set不支持下标操作符,而且没有定义mapped_type类型。在set容器中,value_type不是pair类型,而是与key_type相同的类型。它们指的都是set中存储的元素类型。

  14. 与map容器的操作一样,带有一个键参数的insert返回pair类型对象,包含一个迭代器和一个bool值,迭代器指向拥有改建的元素,而bool值表明是否添加了元素。使用迭代器对的insert版本返回void类型。

  15. 由于键不要求是唯一的,因此每次调用insert总会添加一个元素。

  16. 在multimap和multiset容器中,如果某个键对应多个实例,则这些实例在容器中将相邻存放。lower_bound返回的迭代器不一定指向拥有特定键的元素。如果改键不在容器中,则lower_bound返回在保持容器元素顺序的前提下该键应被插入第一个位置。



2010-11-4(下午,泛型算法)

  1. ……因为他们实现相同的操作,所以称之为“算法”;而“泛型”指的是它们可以操作在多种容器类型上……

  2. 类似地,由于指针的行为与作用在内置数组上的迭代器一样,因此也可以使用find来搜索数组……

  3. 泛型算法本身从不执行容器操作,只是单独依赖迭代器和迭代器操作实现。算法基于迭代器及其操作实现,而并非基于容器操作。这个事实也许比较意外,但本质上暗示了:使用“普通”的迭代器时,算法从不修改基础容器的大小。正如我们所看到的,算法也许会改变存储在容器的元素的值,也许会在容器内移动元素,但是,算法从不直接添加或删除元素。

  4. 除了少数例外情况,所有算法都在一段范围内的元素上操作,我们将这段范围称为“输入范围(input range)”。带有输入范围参数的算法总是使用头两个形参标记该范围。

  5. 理解算法的最基本方法是了解该算法是否读元素,写元素或者对元素进行重新排序。

  6. 通常,泛型算法都是在标记容器(或其他序列)内的元素范围的迭代器上操作的。标记范围的两个实参类型必须精确匹配,而迭代器本身必须标记一个范围:它们必须指向同一个容器中的元素(或者超出容器的下一位置),并且如果两者不相等,则第一个迭代器通过不断地自增,必须可以到达第二个迭代器。

  7. 有些算法直接将数据写到输入序列,另外一些则带有一个额外的迭代器参数指定写入目标。这类算法将目标迭代器用作输出的位置。还有第三种算法将指定数目的元素写入某个序列。

  8. 对指定数目的元素写入运算,或者写入目标迭代器的算法,都不检查目标的大小是否足以存储要写入的元素。

  9. 通常,用迭代器给容器元素赋值时,被赋值的是迭代器所指向的元素。而使用插入迭代器赋值时,则会在容器中添加一个新元素,其值等于赋值运算的右操作数的值。

  10. 谓词是做某些检测的函数,返回用于条件判断的类型,指出条件是否成立。

  11. 标准库所定义的迭代器不依赖于特定的容器。事实上,C++语言还提供了另外三种迭代器:(1)插入迭代器(2)iostream迭代器(3)反向迭代器。

  12. 流迭代器只定义了最基本的迭代器操作:自增,解引用和赋值。此外,可比较两个istream迭代器是否相等(或不等)。而ostream迭代器则不提供比较运算。

  13. 流迭代器都是类模板:任何已定义输入操作符(>>操作符)的类型都可以定义istream_iterator。类似地,任何已定义输出操作符(<<操作符)的类型也可以定义ostream_iterator.


2010-11-7(续上)

  1. 由于不能反向遍历流,因此流迭代器不能创建反向迭代器。

  2. 使用普通的迭代器对反向迭代器进行初始化或赋值时,所得到的迭代器并不是指向原迭代器所指向的元素。

  3. 迭代器可根据所提供的操作集进行分类。

  4. 所有标准库容器提供的迭代器都至少达到双向迭代器的要求。

  5. C++标准为所有泛型和算术算法的每一个迭代器形参指定了范围最小的迭代器种类。

  6. 向算法传递无效的迭代器类别所引起的错误,无法保证会在编译时被捕获到。

  7. 算法最基本的性质是需要使用的迭代器种类。所有算法都指定了它的每个迭代器形参可使用的迭代器类型。

  8. 尽管几乎所有算法都有输入范围,但算法是否使用其他形参取决于它所执行的操作。

  9. 如果dest是容器上的迭代器,则算法将输出内容写到容器中已存在的元素上。更普遍的用法是,将dest与某个插入迭代器或者ostream_iterator绑定在一起。

  10. 带有beg2而不带end2的算法将beg2视为第二个输入范围的首元素,但没有指定该范围最后一个元素。这些算法假定以beg2开始的范围至少与beg和end指定的范围一样大。

  11. 标准库为这些算法提供另外命名的版本,而非重载版本,其原因在于这两种版本的算法带有相同数目的形参。……此时,如果使用重载版本,则可能导致二义性,尽管这个可能出现的几率很低。

  12. 对于list对象,应该优先使用list容器特有的成员版本,而不是泛型算法。

  13. List容器特有的算法与其泛型算法之间有两个至关重要的差别。其中一个是remove和unique的list版本修改了其关联的基础容器……另一个差别是list容器提供的merge和splice运算会破坏它们的实参。

    14. 习题11.23,五种迭代器各自支持的操作。

    输入迭代器

    1. 相等与不等 2)前后置自增

    3)右操作数解引用 4)箭头操作符

    输出迭代器

    1. 前后置自增 2)左操作数解引用

    (对迭代器值要求恰好写入一次)

    前向迭代器

    1. 所有输入输出迭代器的操作

    2. 同一元素的多次读写

    3. 迭代器复制,记录

    双向

    1. 前向迭代器的所有操作

    2. 前后置自减

    随机迭代器

    1. 双向迭代器的所有操作 2)所有关系操作符

    1. 与整型数值运算 4)迭代器减法

    5)下标操作


    2010-11-9(晚上 类)

    1. 最简单地说,类就是定义了一个新的类型和一个新的作用域。

    2. 在类内部定义的函数默认为inline.

    3. Const成员(函数)不能改变其所操作的对象的数据成员。Const必须同时出现在声明和定义中,若只出现在其中一处,就会出现一个编译时错误。

    4. 类背后蕴含的基本思想是数据抽象和封装。数据抽象是一种依赖于接口和实现分离的编程(和设计)技术。……封装是一项将低层次的元素组合起来形成新的,高层次实体的技术。

    5. 在C++中,使用访问标号来定义类的抽象接口和实现封装。……类型的数据抽象视图由其public成员定义。……private封装了类型的实现细节。

    6. 并非所有类都必须是抽象的。……一些类,例如pair,确实没有抽象接口。……尽管如此,这样的类型通常还是有成员函数的。

    7. 设计类的接口是,设计者应该考虑的是如何方便类的使用;使用类的时候,设计者就不应该考虑类如何工作。

    8. 在类的外部定义inline的一个好处是可以使得类比较容易阅读。

    9. 不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。

    10. 因为只有当类定义体完成后才能定义类,因此类不能具有自身类型的数据成员。然后,只要类名一出现就可以认为该类已声明。因此,类的数据成员可以是指向自身的指针或引用。

    11. 定义对象时,将为其分配存储空间,但(一般而言)定义类型时不进行存储分配。


    未知时间(类)

    1. public的类型别名杂类体外使用需要作用域限定符;在类体外成员函数定义中,出现成员名之后,不用限定符。

    2. Inline成员函数在类体成员类外声明一次即可。类体内定义的成员函数默认为inline。

    3. Const成员函数不能修改非mutable的数据成员。

    4. Const类对象只能调用const成员函数。

    5. 成员函数可以返回本类对象及引用,指针。返回对象时可以设定const属性。

    6. 定义类的时候不能具有自身类型的数据成员,但可以是指向自身类型的指针或引用。

    7. 一旦遇到右花括号,类的定义就结束了。


    未知时间(同上)

    1. const构造函数是不必要的。

    2. 构造函数的工作是初始化对象。

    3. 构造函数初始化式只在构造函数的定义中而不是声明中指定。

    4. 从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。

    5. 在构造函数初始化列表中没有显示提及的每个成员,使用与初始化变量相同的规则来进行初始化。运行该类型的默认构造函数,来初始化类类型的数据成员。内置或复合类型的成员初始化值依赖于对象的作用域:在局部作用域中这些成员不被初始化,而在全局作用域中它们被初始化为0。

    6. 必须对任何const或引用类型的成员以及没有默认构造函数的类类型的任何成员使用初始化式。

    7. 构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。成员被初始化的次序就是定义成员的次序。

    8. 初始化的次序常常无关紧要。然而,如果一个成员是根据其他成员而初始化,则成员初始化的次序是至关重要的。

    9. 安装与成员声明一致的次序编写构造函数初始化列表是个好主意。此外,尽可能避免使用成员来初始化其他成员。

    10. 初始化式可以是任意表达式。

    11. 只要定义一个对象时没有提供初始化式,就使用默认构造函数。为所有形参提供默认实参的构造函数也定义了默认构造函数。

    12. 实际上,如果定义了其他构造函数,则提供一个默认构造函数几乎总是对的。

    13. 可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换。

    14. 当构造函数被声明为explicit时,编译器将不使用它作为转换操作符。

    15. 任何构造函数都可以用来显示地创建临时对象。

    16. 通常,除非有明显的理由想要定义隐式转换,否则,但形参构造函数应该为explicit。将构造函数设置为explicit可以避免错误,并且当转换有用时,用户可以显示地构造对象。

    17. 每个static数据成员是与类关联的对象,并不与该类的对象相关联。

    18. Static成员函数没有this形参,它可以直接访问所属类的static数据成员,但不能直接使用非static成员。

    19. 因为static成员不是任何对象的组成部分,所以static成员函数不能被声明为const。毕竟,将成员函数声明为const就是承诺不会修改该函数所属的对象。

    20. Static数据成员的类型可以是该成员所属的类类型。Static数据成员可用作默认实参。

    21. 友元声明将已命名的类或非成员函数引入到外围作用域中。用友元引入的类名和函数(定义或声明),可以像预先声明一样使用。



    ————————————————————————————————————————————————已打印———————————————————————————————————————————————————



    2010-11-26晚(复制控制)

    1,复制构造函数,赋值操作符和析构函数总称为复制控制。

    2,实现复制控制操作最困难的部分,往往在于识别何时需要覆盖默认版本。

    3,c++支持两种初始化形式:直接初始化和复制初始化。

    4,合成复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制。数组成员的复制是个例外。虽然一般不能复制数组。但如果一个类具有数组成员,则合成复制构造函数将复制数组。

    5,为了防止复制,类必须显式声明其复制构造函数为private。想要连友元和成员中的复制也禁止,就可以声明一个(private)复制构造函数但不对其定义。

    6,通过声明(但不定义)private复制构造函数,可以禁止任何复制类类型对象的尝试:用户代码中的复制尝试将在编译时标记为错误。而成员函数和友元函数中的复制尝试将在链接时导致错误。

    7,如果定义了复制构造函数,也必须定义默认构造函数。

    8,实际上,应将这两个操作(复制和赋值)看做是一个单元。如果需要其中一个,我们几乎也可以肯定需要另一个。

    9,变量在超出作用域时应该自动撤销……动态分配的对象只有在指向该对象的指针被删除时才撤销。……撤销一个容器(不管是标准库容器还是内置数组)时,也会运行容器中的类类型元素的析构函数)

    10,析构函数通常用于释放再构造函数或在对象生命期内获取的资源。

    11,如果类需要析构函数,则它也需要赋值操作符和复制构造函数,这是一个有用的经验法则。这个规则常称为三法则,指的是如果需要析构函数,则需要所有这三个复制控制成员。

    12,与复制构造函数或赋值操作符不同,编译器总是会为我们合成一个析构函数。

    13,合成析构函数并不删除指针成员所指向的对象。

    14,析构函数与复制构造函数或赋值操作符之间的一个重要区别是,即使我们编写了自己的析构函数,合成析构函数仍然运行。

    15,复制控制的赋值操作符接收单个形参,且该形参是同一类类型对象。




    2011-4-4(中午)重载操作符与转换

    1,用于内置类型的操作符,其含义不能改变。

    2,操作符的优先级,结合性或操作数数目不能改变。

    3,重载操作符并不保证操作数的求值顺序。

    4,一般将算术和关系操作符顶以为非成员函数,而将赋值操作符定义为成员。

    5,操作符定义为非成员函数时,通常必须将他们设置为所操作类的友元。

    6,重载逗号,取地址,逻辑与,逻辑或等操作通常不是好做法。这些操作具有有用的内置含义,如果定义了自己的版本,就不能再使用这些内置含义。

    7,赋值,下标,调用(()),和成员访问箭头等操作符必须定义为成员,将这些操作符定义为非成员函数将导致编译时错误。

    8,对称的操作数,如算术操作符,相等操作符,关系操作符和位操作符,最好定义为普通非成员函数。

    9,当定义符合标准库iostream规范的输入或输出操作符的时候,必须使它成为非成员操作符。

    10,与输出操作符类似,输入操作符的第一个形参是一个引用,指向它要读的流,并且返回的也是对同一个流的引用。它的第二个形参是对要读入的对象的非const引用,该形参必须为非const,因为输入操作符的目的是将数据读到这个对象中。

    11,更重要但通常重视不够的是,输入和输出操作符有如下区别:输入操作符必须处理错误和文件结束的可能性。

    12,设计输入操作符时,如果可能,要确定错误恢复措施,这很重要。

    13,注意,为了与内置操作符保持一致,加法返回一个右值,而不是一个引用。

    14,类赋值操作符必须是类的成员,以便编译器可以知道是否需要合成一个。

    15,下标操作符必须定义为类成员函数。

    16,类定义下标操作符时,一般需要定义两个版本:一个为非const成员并返回引用,另一个为const成员并返回const引用。

    17,箭头操作符必须定义为类成员函数。解引用操作符不要求定义为成员,但将它作为成员一般也是正确的。

    18,重载箭头操作符必须返回指向类类型的指针,或者返回定义了自己的箭头操作符的类类型对象。

    19,C++语言不要求自增操作符或自减操作符一定作为类的成员,但是,因为这些操作符改变对象的状态,所以更倾向于将它们作为成员。

    20,为了与内置类型一致,前缀式操作符应返回被增量或减量对象的引用。

    21,后缀式操作符函数接受一个额外的(即无用的)int型形参。

    22,为了与内置操作符一致,后缀式操作符应返回旧值,并且,应作为值返回,而不是返回引用。

    23,如果想要使用函数调用来调用后缀式操作符,必须给出一个整型实参值。

    ps:做这些笔记的时候是一年前多了。当时还在做着ACM,学这些似乎只是抱着充实自己的心态,当时最想的似乎就是看完整本书,但最终还是在面向对象的部分停下来了。现在很多东西都忘了,毕竟这样学而没有实际使用,肯定很容易忘的。可能当时也是出现了这么个想法而停下来的吧,至少应该是其中一个原因。这份笔记似乎在硬盘里丢失过一次,最后在金山快盘里找回来的。2011-12-4

     


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理