学习C++Primer心得

时间:2024.3.7

学习C++Primer心得和一些问题

1、在VC的MFC程序中能否使用cout输出?

答:不能。必须使用CDC来进行输出。

2、C++中子类的构造函数是否会自动调用基类构造函数?

答:会。如果在子类的构造函数中不显式指定调用基类构造函数,则将自动调用基类缺省构造函数,所以基类一定要有缺省构造函数。如果子类的构造函数除了调用基类构造函数以外什么都不做,不能不写,必须写一个空函数。

3、子类对象的初始化过程是怎样的?

答:先调用基类构造函数来初始化相关的基类子对象,然后再执行子类(派生类)的构造函数。

4、名字空间的使用有哪些方式?

答:大概有三种方式:

l 使用名字空间别名加上名称限制修饰符

namespace LIB = IBM_Canada_Laboratory;

LIB::Array<int> ia(1024);

l using指示符,使名字空间内的所有声明可见

using namespace IBM_Canada_Laboratory;

l using声明,使名字空间中的单个声明可见

using IBM_Canada_Laboratory::Matrix;

using指示符和using声明的本质是不同的。

5、如何声明一个对象已经在文件外被定义?

答:使用extern来声明。可以在多个地方多次声明同一个对象,但是一个对象只能被定义一次,而且多个声明必须明确无误的指向这个定义实体。声明不分配内存,定义分配内存。

6、类的缺省构造函数会为类的数据成员初始化吗?

答:不会。只会分配内存,不会初始化。必须在缺省构造函数中显式进行初始化。

7、下面的对象初始化是调用赋值操作符吗?

BaseClass base1; BaseClass base2 = base1;

答:不是。是调用拷贝构造函数。

8、类中的常量数据成员应该在哪里被初始化?

答:应该在类的成员初始化列表中初始化。

9、typedef引入了新的类型吗?

答:没有。它仅仅是用来为内置或用户定义的数据类型引入助记符号。

10、空指针解引用会出错吗?

答:会。对指针解引用之前一定要先确定其不为零。

11、算术异常会抛出实际异常吗?

答:算术异常是指计算过程中出现不正确或未定义的值,如除以0或溢出。但是不会导致抛出实际的异常。

12、size_t是什么类型?

答:这是用typedef引入的类型助记符,代替unsigned int。

13、用sizeof可以获得一个数组的长度,为什么在传递数组给函数时还要带上长度参数? 答:用sizeof是可以获取一个数组的长度,如int a[10]; int len = sizeof(a)/sizeof(int);。但是,在用数组作为参数传递给函数时,数组变为了指针,所以在函数内部不能获取数组长度。

14、算术转换的指导原则是什么?

答:有两个通用原则:一、类型总是被提升为较宽的类型;二、所有含有小于整型的有序类型,在计算之前,其类型都会被转换成整型。

15、都有哪些显式强制转换操作符?它们的功能是什么?

答:有static_cast、const_cast、dynamic_cast和reinterpret_cast。static_cast可用来执行任何编译器可隐式执行的任何类型转换。const_cast用来将常量对象或指针转换为非常量对象或指针。reinterpret_cast通常对于操作数的位模式执行一个比较低层次的重新解释,相当于旧式的指针强制转换。dynamic_cast支持在运行时刻识别由指针或引用指向的类对象。

16、对于类对象的定义为什么最好在用之前才定义,而不要在一开始就定义?

答:对于内置类型,它的定义只是分配内存,不会做更多的处理。而对于类对象,它的定义除了分配内存外,还要调用构造函数。因此,如果在函数或语句块一开始就定义类对象,必然会导致构造函数的调用,而这些调用的开销可能是不必要的。这使得程序的效率下降。因此,最好是当真正要用的时候才去定义比较好。

17、容器类型的容量与长度的区别?

答:容量只与连续存储的容器类相关,如vector、deque或string,而对于非连续存储的容器类,如list,则没有容量的概念。它是指在容器下一次需要增长自己之前能够被加入到容器中的元素的总数,可调用capacity()操作来获得。长度是指容器当前拥有元素的个数,可调用size()操作来获得。容量的增长方式是与具体实现有关的。

18、迭代器的基本概念是什么?

答:迭代器提供了一种一般化的方法,对顺序或关联容器类型中的每个元素进行连续访问。

19、什么时候函数应该采用引用参数?

答:一、希望改变实参的值,又不想用指针操作;二、希望返回更多的值;三、实参为大型类对象,按值传递效率低。

20、函数参数表中的省略号是什么意思?

答:省略号告诉编译器不用对这个函数的参数进行参数类型检查了,参数可以有0个或多个。

21、extern的用法有哪些?

答:一、链接指示符,用来声明函数由其他语言编写,如extern “C”;二、声明一个全局变量,表示该变量在其他文件中定义了。声明函数时可省略掉。

22、函数名和函数名取地址都可以作为函数指针吗?

答:可以。因此,函数指针和函数指针解引用都可以用来调用函数。

23、类型安全链接的含义是什么?

答:在编译阶段,有一种机制可以把函数参数的类型和数目编码在函数名中,该机制叫做类型安全链接。所以,一个函数并非仅仅通过函数名来识别的,这是函数重载的基础。

24、静态对象会被缺省初始化吗?

答:会。缺省初始化为0。

25、用delete删除动态内存分配的空间时,是否要先判断指针为NULL?

答:不用,程序内部会自动判断。但是最好在删除之后将指针设为NULL。

26、using声明和using指示符的本质有什么不同?

答:using声明相当于在声明的语句处引入一个别名,该别名与声明的名称空间中的同名对象或函数一样。using指示符相当于把名称空间在其定义处就地剥开,并不引入新的别名。

27、函数重载时是否考虑const参数的影响?

答:对于const对象来说,函数重载不考虑,即认为带有const和非const对象参数的函数是相同的函数声明。而对于const指针或引用,则认为是不同的函数声明。

28、extern “c”链接指示符能否将c函数引入到重载函数集合中?

答:能,但只能引入一个。即c语言的函数只能有一个属于重载函数集合。

29、函数模板实例化的过程中,模板类型参数是如何被确定类型的?

答:是通过调用函数时的实参类型来推演模板的参数类型的,该过程称为模板实参推演。

30、异常处理子句catch中声明异常类对象有何用?

答:这个异常类对象可以捕获异常发生时,由throw子句所产生异常类对象。如果改为异常类对象的引用,则还可进一步修改由throw子句抛出的异常类对象,并重新抛出。

31、如果函数抛出了其异常规范之外的异常时会出现什么情况?

答:系统调用C++标准库定义的函数unexpected(),其将调用terminate()。

32、指定一个空的异常规范和不指定异常规范一样吗?

答:不一样。空的异常规范表示该函数不能抛出任何异常,而不指定异常规范表示该函数可以抛出任何异常。

33、在程序设计中异常设计是否很困难?

答:是。异常是库接口的一部分,什么时候抛出异常,什么时候库自己处理,在那些调用程序中处理抛出的异常都是一个问题。

34、STL的主要组成部分包括哪些?

答:有容器类(包含数据)、算法(对数据的操作)、迭代器(连接容器和算法)以及函数对象(定义具体的操作方式)。

35、函数对象的一般用法如何?

答:一般将函数对象定义为一个类,然后需要重载该类的调用操作符。一般的泛型算法都可以接受函数对象或函数指针。函数指针的用法缺点是不能支持函数内联。

36、函数对象从哪里来?

答:一、标准库预定义的一组算术、关系和逻辑函数对象;二、定义自己的函数对象;三、一组预定义的函数适配器,对函数对象进行特殊化或者扩展。

37、什么是函数适配器?

答:标准库提供的一组特殊的类,用来特殊化或者扩展函数对象。它被分成下面两类:绑定器(binder)和取反器(negator)。

38、排序算法能用在list上吗?

答:不能,也不能用在联合容器set或map上。

39、类在定义之前能定义类对象吗?

答:不能。但可以先声明这个类,然后定义该类的指针或引用。

40、声明const成员函数时是否要在定义函数时也加上const?

答:在声明和定义函数的时候都必须加上const。

41、const成员函数有什么要求?

答:要求在const函数当中不能修改类的数据成员。对于那些不修改数据成员的函数最好将其声明为const函数。有一个例外,如果数据成员定义为mutable类型,则在const函数中也可以修改该数据成员。

42、静态数据成员如何初始化?

答:应该在类体定义之外初始化,但不能在类的构造函数中初始化,因为静态成员不属于某个类对象,而是属于类的。静态数据成员可通过类的限定修饰符来访问。

43、什么是嵌套类?

答:在一个类A的类体中定义的另一个类B,称为嵌套类(nested class)。

44、如何调用类的缺省构造函数定义类对象?

答:不能这样写:ClassA obj(); 这样会被认为声明了一个函数,必须这样写:ClassA obj;。一般情况都必须为类提供缺省构造函数。

45、应用在构造函数上的explicit有什么作用?

答:一般构造函数如果只含有一个参数,则编译器可以隐式的调用该构造函数,将参数类型转换为类类型,但是这种隐式转换在某些时候是存在隐患的,在构造函数前面加上explicit就是为了防止这种隐式调用发生。

46、一个类对象的容器类是如何初始化的?

答:先创建该类的临时对象,并用缺省构造函数初始化;然后将临时对象通过拷贝构造函数拷贝到容器类当中的所有类对象上;然后删除临时对象。

47、类的成员类对象在构造函数中初始化时,放在成员初始化表中与放在构造函数体中有什么区别?

答:实际上类的初始化分为两个阶段,第一个阶段是初始化阶段,它调用所有成员类的缺省构造函数或者调用成员初始化表;第二个阶段是计算阶段,它调用函数体内的语句。所以如果将成员类对象放在函数体中初始化,实际上是先调用缺省构造函数,然后执行赋值操作,效率大大降低。一般准则是所有的成员类对象都应该将其放在成员初始化表中。另外对于const成员和引用成员必须在成员初始化表中。

48、拷贝构造函数和拷贝赋值操作符是一回事吗?

答:不是。但一般来说,两者应该同时定义或者禁止。

49、前置和后置++和--操作符函数原型有什么不同?

答:后置的操作符函数参数比前置的操作符函数多一个int参数,该参数在函数定义中并不会使用。

50、转换函数与构造函数都可完成类型转换,它们有什么区别?

答:构造函数(带有一个参数的)可完成其它类型向该类类型转换操作,而转换函数是从该类类型向指定的类型转换的操作。转换函数原型不能含有返回值和参数。它的定义形式如下:operator type() {}。

51、用户定义的转换包括什么?

答:包括调用转换函数或一个参数的构造函数。

52、标准C++支持为模板参数提供默认实参吗?

答:支持,但VC++6.0不支持。

53、类模板的成员函数的实例化是不是随着类模板的实例化进行的?

答:不是,成员函数的实例化是当函数被调用的时候才实例化的。

54、面向对象编程的基础是什么?

答:两个基础:多态(polymorphism)和动态绑定(dynamic binding)。多态指的是基类的指针或引用可以指向基类派生的任何子类,即一个基类指针或引用可能的实际类型是多种的。动态绑定指的是当用基类指针调用函数时,如果函数是虚函数(virtual function),则实际调用哪个函数是在运行时刻根据指针的实际类型来动态决定了。

55、在面向对象设计中是否一次性完成类结构设计?

答:一般很难,通常是反复迭代,要求对不断演化过程中的类层次结构进行添加和修改。

56、基类的一般用法如何?

答:定义基类的指针或引用(如果包含纯虚函数,则不能定义抽象基类的对象),然后用它们来操纵任何从该基类派生来的子类对象。

57、面向对象基类的设计主要要考虑的问题是什么?

答:确定哪些成员为protected;确定哪些函数为虚函数。

58、派生类的虚函数原型是否要指定virtual?

答:可要可不要。

59、派生类能否定义函数,以重载基类当中的函数?

答:可以。采用在派生类中使用using声明可做到。

60、派生类的构造函数执行包括几个步骤?

答:三个步骤:基类构造函数;成员类构造函数;派生类构造函数。

61、类的构造函数的访问权限只能是public吗?

答:不是。可以是protected和private两种。当构造函数为protected时,只希望在派生类中构造该类。当构造函数为private时,不希望任何地方来构造该类,如果有友元类,可以在友元类中构造该类。

62、派生类的构造函数要调用基类的缺省构造函数,是否要显式调用?

答:不用。会被隐式调用。

63、析构函数是否也可以做成动态绑定?

答:可以,只要声明为虚函数。

64、虚拟函数在.cpp文件中定义时是否要加virtual?

答:不能加。

65、如何静态调用虚拟函数?

答:用类域限定符。

66、clone函数是干什么的?

答:是用来克隆一个类对象,并返回克隆后的对象指针。

67、dynamic_cast是干什么用的?

答:它是RTTI(运行时刻类型识别)的一部分。它支持在运行时刻查询一个多态指针或引用所指向的对象的实际类型。

68、多继承下的多个基类一般与派生类存在什么关系?

答:一般每个基类代表派生类完整接口的一个方面。

69、private继承意味着什么?

答:由于基类的所有成员(public和protected成员)都变成子类的private成员,包括基类的公共接口也变成私有的了,因此,子类不能给外部直接提供基类的公共接口,而必须重新实现它们。这往往是由于子类仅仅希望得到基类的数据成员,但不希望继承基类的接口。

70、什么是RTTI?

答:运行时刻类型识别,可使得程序可以知道指向基类的指针或引用实际所指的对象的类型。它提供了两个操作符:dynamic_cast,允许在运行时刻进行类型转换,把基类指针转换成派生类指针;typeid,指出指针或引用的实际派生类型。

71、typeid操作符如何使用?

答:typeid的参数如为类对象,则返回该类对象的实际类型。如为类指针,则返回该指针的定义类型。返回的值实际上是一个type_info类。

72、类成员函数的声明和定义中都要指定异常规范吗?

答:都要。


第二篇:C Primer 中文版(第四版)学习笔记


C++ Primer 中文版(第四版)学习笔记

第一章 快速入门

1. 每个C++程序都包含一个或多个函数,而且必须有一个命名为main。函数由执行函数功能的语句序列组成;

2. main函数是唯一被操作系统显式调用的函数;

3. main函数的形参个数是有限的

4. 函数体是函数定义的最后部分,是以花括号开始并以花括号结束的语句块;

5. 注释不会增加可执行程序的大小,编译器会忽略所有注释;

6. 我们注释的风格是在注释的每一行以星号开始,指明整个范围是多行注释的一部分;

7. 我们倾向于吧确定函数边界的花括号自成一行,且缩进复合的输入或输出表达式从而使操作符排列整齐;

8. 标准库的头文件用尖括号< >括起来,非标准库的头文件用双引号“ ”括起来;

第一部分基本语言

第二章 变量和基本类型

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

2. 在位这一级上,存储器是没有结构和意义的;让存储具有结构的最基本方法是用块处理存储;

3. 建议:使用内置算术类型;

4. 只有内置类型存在字面值,没有类类型的字面值,也没有任何标准库类型的字面值;

5. 没有short类型的字面值常量;

6. 不可打印字符和特殊字符都用转义字符书写,转义字符都以反斜线符号开始;

7. 未定义行为源于编译器不能检测到的程序错误或太麻烦一直无法检测的错误;

8. C++是一门静态类型语言,在编译时会做类型检查;

9. 左值可以出现在赋值语句的左边或右边,右值只能出现在的赋值语句的右边;

10. 变量是左值,数字字面值是右值;

11. 对象就是内存中具有类型的区域;

12. 标识符不能包含两个连续的下划线,也不能以下划线开头后面紧跟一个大写字母。有些标识符(在函数外定义的标识符)不能以下划线开头;

13. C++支持两种初始化变量的形式:复制初始化和直接初始化。复制初始化语法用等号(=),直接初始化则把初始化式放在括号中;

14. 初始化不是复制:初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替;

15. 在函数体外定义的变量都初始化成0,在函数体里定义的内置类型变量不进行自动初始化;

16. 在一个程序中,变量有且仅有一个定义,但可以声明多次。

17. 定义也是声明,可以通过使用extern关键字声明变量名而不定义它。extern声明包括对象名、对象类型和对象类型前的关键字extern,extern声明不是定义,也不能分配存储空间;

18. 只有当extern声明位于函数外部时才可以含有初始化式,因为已初始化的extern声明被当作是定义,所以该变量任何随后的定义都是错误的,随后含有初始化式的extern声明也是错误的;

19. 用来区分名字不同意义得上下文称为作用域,作用域是程序的一段区域;

20. 一般来说,名字从其声明点开始直到其声明所在的作用域结束处都是可见的;

21. 局部变量的定义会屏蔽相同名字的全局变量定义;

22. 在全局作用域声明的const变量是定义该对象的文件的局部变量。此变量只存在于那个文件中,不被其他文件访问;

23. 不能定义引用类型的引用,但可以定义任何其他类型的应用;

24. 引用必须用于与该引用同类型的对象初始化;

25. 作用在引用上的所有操作事实上都是作用在该引用绑定的对象上;

26. 初始化是指明引用指向哪个对象的唯一方法,当引用初始化后,只要该引用存在,它将绑定到初始化时指向的对象。不可能将引用绑定到另一个对象;

27. 将普通的应用绑定到const对象是不合法的;

28. 非const引用只能绑定到与该引用同类型的对象,const引用则可以绑定到不同但相关的类型的对象或绑定到右值;

29. 默认地,第一个枚举成员赋值为0,后面的每个枚举成员赋的值比前面的大1;

30. 常量表达式是编译器在编译时就能够计算出结果的整型表达式;

31. 不能改变枚举成员的值;

32. 枚举成员的对象初始化或赋值,只能通过其枚举成员或同意枚举类型的其他对象来进行;

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

第三章 标准库类型

1. string对象比较操作是区分大小写的,即同一个字符的大小写形式被认为是两个不同的字符;

2. 一个容器中的所有对象都必须是同一种类型的;

3. 所谓的“缓冲区溢出”错误就是对不存在的元素进行下标操作的结果;

4. 迭代器是一种检查容器内元素并遍历元素的数据类型,因为迭代器对所有的容器都适用,现代C++程序更倾向于使用迭代器而不是下标操作访问容器元素,即使对支持下标操作的vector类型也是这样;

5. 每种容器类型还定义了一种名为const_iterator的类型,该类型只能用于读取容器内元素,但不能改变其值;

6. 任何改变vector长度的操作都会是以存在的迭代器失效;

7. 在定义bitset时,要明确bitset含有多少位,须在尖括号内给出它的长度值;

8. 从string对象读入位集的顺序是从右向左;

9. string对象和bitset对象之间是反向转化的:string对象的最右边字符(即下标最大的那个字符)用来初始化bitset对象的低阶位(即下标为0的位)。

第四章 数组和指针

1. 如果没有显式提供元素初值,则数组元素会像普通变量一样初始化: 在函数体外定义的内指数组,其元素均初始化为0;

在函数体类定义的内置数组,其元素无初始化;

不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;

如果该类没有默认构造函数,则必须为该数组元素提供显式初始化;

2. 指针是指向某种类型对象的复合数据类型,适用于数组的迭代器;

3. C++语言无法检测指针是否未被初始化,也无法区分有效地址和由指针分配到的存储空间中存放的二进制位形成的地址;

4. 指针只能初始化或赋值为同类型的变量地址或另一指针;

5. C++提供了一种特殊的指针类型void*,它可以保存任何类型对象的地址;

6. void*指针只支持几种有限的操作:与另一个指针进行比较:向函数传递void*指针或从函数返回void*指针;给另一个void*指针赋值;不允许使用void*指针操纵它所指向的对象;

7. 允许把非const对象的地址赋给指向const对象的指针;

8. 可以修改const指针所指向的值,不能保证指向const的指针所指对象的值一定不能修改;

9. 可以把指向const的指针理解为“自以为指向const的指针”;

10. 任何企图给const指针赋值的行为(即使给原指针赴会同样的值)都会导致编译时的错误;

11. C风格字符串是以空字符null结束的字符数组;

12. 与数组变量不同,动态分配的数组将一直存在,直到程序显式释放它为止;

13. 每一个程序在执行时都占有一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区或堆;

14. 可以使用跟在数组长度后面的一对空圆括号,对动态分配的数组元素做值初始化;

15. 如果我们在自由存储区中创建的数组存储了内置类型的const对象,则必须为这个数组提供初始化,唯一的方法是对数组做值初始化;

16. C++允许定义类类型的const数组,但该类类型必须提供默认构造函数;

17. 调用new动态创建长度为0的数组是合法的;

18. 可使用C风格字符串对string对象进行初始化或赋值;

string类型的加法操作需要两个操作数,可以使用C风格字符串作为其中的一个操作数,也允许将C分隔字符串用作复合赋值的右操作数;

在要求C风格字符串的地方不可直接使用标准库string类型对象;

19. 严格来讲,C++中没有**数组,通常所指的**数组其实就是数组的数组;

20. 如果表达式只提供了一个下标,则结果获取的元素是该行下标索引的内层数组;

第五章 表达式

1. 短路求值:逻辑与和逻辑或操作符总是先计算其左操作数,然后再计算其右操作数。只有在仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数;

2. 赋值操作符的左操作数必须是非const的左值;

3. 数组名是不可修改的左值:因此数组不可用作赋值操作的目标;

4. 只要被赋值的每个操作数都具有相同的通用类型,C++语言允许将这多个赋值操作写在一个表达式中:

int ival,jval;

ival=jval=0;

5. 将sizeof用于表达式expr是,没有计算表达式expr的值。特别是在sizeof *p 中,指针p可以持有一个无效地址,因为不需要对p做解引用操作;

6. C++保证:删除0值得指针是安全的;

7. 动态创建的const对象必须在创建时初始化,并且一经初始化,其值就不能再修改;

8. 用作条件的表达式被转换为bool类型;

9. 用一表达式初始化某个变量,或将一个表达式赋值给某个变量,则该表达式被转换为该变量的类型;

10. 数组用作取地址&操作符的操作数或sizeof操作符的操作数时,或用数组对数组的引用进行初始化时,不会将数组转换为指针;

11. 指向任意数据类型的指针都可转换为void*类型,整形数值常量0可转换为任意指针类型;

12. C++自动将枚举类型的对象或枚举成员转换为整形,其转换结果可用于任何要求使用整数值的地方;

13. 当使用非const对象初始化const对象的引用时,系统将非const对象转换为const对象。此外,还可以将非const对象的地址(或非const指针)转换为指向相关const类型的指针;

14. 将istream类型转换为bool类型意味着要检验流的状态;

15. 命名的强制类型转换符号的一般形式如下:

cast-name<type>(expression);

其中cast-name为static_cast 、dynamic_cast 、const_cast和reinterpret_cast之一,type为转换的目标类型,而expression则是被强制转换的值;

16. 编译器隐式执行任何类型转换都可以有static_cast显示完成;

第六章 语句

1. 复合语句,通常被称为块,是用一对花括号括起来的语句序列(也可能是空的);

2. else分支只能后接单个语句;

3. IO类型可以用作条件,但vector类型和string类型一般不可用作条件;

4. 将else匹配给最后出现的尚未匹配的if子句来解决悬垂else问题带来的二义性;

5. 每个case标号的值都必须是一个常量表达式

6. 在循环条件中定义的变量在每次循环里都要经历创建和撤销的过程;

7. 在for语句头定义的任何对象只限制在for循环体里可见;

8. 可以在for语句的初始化语句中定义多个对象,但是不管怎么样,该处只能出现一个语句,因此所有的对象必须具有相同的一般类型;

9. break只能出现在循环或switch结构中,或者出现在嵌套于循环或switch结构中的语句里;

10. continue语句导致最近的循环语句的单次迭代提前结束,对于while和do while语句,继续求解循环条件,而对于for循环,程序流程接着求解for语句头中的expression表达式;

11. goto语句和获得所转移的控制权的带标号的语句必须位于同一个函数内;

12. goto语句不能跨越变量定义语句向前跳转;

第七章 函数

1. 在函数体类定义的变量只有在该函数中才可以访问,这种变量称为局部变量;

2. 实参必须具有与形参类型相同、或者能隐式转换为形参类型的数据类型;

3. 在定义或声明函数时,没有显式指定返回类型是不合法的;

4. 如果两个参数具有相同的类型,则其类型必须重复声明;

5. 参数表中不能出现同名的参数,局部于函数的变量也不能使用与函数任意参数相同

的名字;

6. 每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参;

7. 普通的非引用类型的参数通过复制对应的实参实现初始化;

8. 如果使用引用实参的唯一目的是避免复制实参,则应将形参定义为const引用;

9. 非const引用形参只能与完全同类型的非const对象关联;

10. 当编译器检查数组形参关联的实参时,它只会检查实参是不是指针、指针的类型和数组元素的类型是否匹配,而不会检查数组的长度;

11. 在无法列举出传递给函数的所有实参的类型和数目时,可以使用省略符形参。省略符暂停了类型检查机制。它们的出现告知编译器,但调用函数时,可以有0或多个实参,而实参的类型未知;

12. 允许主函数main没有返回值就可结束。如果程序控制执行到主函数main的最后一个语句后都还没有返回,那么编译器会隐式地插入返回0的语句;

13. 千万不能返回局部变量的引用;

14. 千万不要返回指向局部对象的指针;

15. 定义函数的源文件应包含声明该函数的头文件;

16. 如果有一个形参拥有默认实参,那么,它后面所有的形参都必须有默认实参;

17. 既可以在函数声明也可以在函数定义中指定默认实参。但是,在一个文件中,只能为一个形参指定默认实参一次;

18. 内联函数应该在头文件中定义;

19. 在头文件中加入或修改内联函数时,使用了该头文件的所有源文件都必须重新编译;

20. 类的成员函数都必须在类定义中的花括号里面声明,此后,就不能再为类增加任何成员;

21. 编译器隐式地将在类内定义的成员函数当作内联函数;

22. 每个成员函数都有一个额外的、隐含的形参this(除了static成员函数以外)。在调用成员函数时,形参this初始化为调用函数的对象的地址;

23. 在函数的形参表中包含this指针是非法的;

24. 如果函数被声明为const成员函数,那么函数定义时形参表后面也必须有const;

25. 构造函数和类同名,而且没有返回类型;

26. 一个类可以有多个构造函数,每个构造函数必须有与其他构造函数不同数目或类型的形参;

27. 如果没有为一个类显示定义任何构造函数,编译器将自动为这个类生成默认构造函数;

28. 合成的默认构造函数不会自动初始化内置类型的成员;

29. main函数不能重载;

30. 函数不能仅仅基于不同的返回类型而实现重载;

31. 在C++中,名字查找发生在类型检查之前;

32. 函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值;

33. 将函数指针初始化为0,表示该指针不指向任何函数;

34. 函数的形参可以是指向函数的指针;

35. 允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。

第八章 标准IO库

1. iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象;

2. 如果函数有基类类型的引用形参时,可以给传递其派生类型的对象;

3. 只有支持赋值的元素类型可以存储在vector或其他容器类型里,因此不存在存储流对象的vector或其他容器;

4. 形参或返回类型也不能为流类型。如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用;

5. 为了确保用户看到程序实际上处理的所有输出,最好的方法是保证所有的输出操作都显式地调用了flush或endl;

6. 当输入流和输出流绑定在一起时,任何读输入流的尝试都将首先刷新其输出流关联的缓冲区;

7. 如果在调用tie函数时传递实参0,则打破该流上已存在的捆绑;

8. 关闭流并不能改变流对象的内部状态;

第二部分容器和算法

第九章 顺序容器

1. 顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定;

2. 将一个容器复制给另一个容器时,类型必须匹配:容器类型和元素类型都必须相同;

3. 容器元素类型必须满足以下两个约束:

元素类型必须支持赋值运算;

元素类型的对象必须可以复制;

4. 除了引用类型外,所有内置或复合类型都可用做元素类型;

5. IO库类型不支持复制和赋值,因此不能创建存放IO类型对象的容器;

6. 定义元素是容器的容器时,必须用空格隔开两个相邻的>符号,以示这是两个分开的符号,否则,系统会认为>>是单个符号,为右移操作符,并结果导致编译时错误; example:vector< vector<string> > lines;

7. = = 和!=这两种关系运算适用所有容器;

8. 关系操作符只适用于vector和deque的容器,这是因为只有这两种容器元素提供快速、随机的访问。它们确保可根据元素位置直接有效地访问指定容器元素;

9. C++语言使用一对迭代器标记迭代器范围,这两个迭代器分别指向同一个容器中的两个元素或超出末端的下一位置;

10. 所有顺序容器都支持push_back操作,提供在容器尾部插入一个元素的功能;

11. 为了避免存储end迭代器,可以在每次做完插入运算后重新计算end迭代器;

12. 比较的容器必须具有相同的容器类型,而且其元素类型也必须相同;

13. C++语言只允许两个容器做其元素类型定义的关系运算;

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

15. 寻找一个指定元素的最简单方法是使用标准库的find算法;

16. erase、pop_front和pop_back函数通常使指向被删除元素的所有迭代器失效。对于vector容器,指向删除点后面的元素的迭代器通常也会失效。而对于deque容器,如果删除

时不包含第一个元素和最后一个元素,那么读deque容器相关的所有迭代器都会失效;

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

18. 要交换的容器的类型必须匹配:操作数必须是相同类型的容器,而且所储存的元素类型也必须相同;

19. 对于大部分应用,使用vector容器时最好的,原因在于,标准库的实现者使用这样的内存分配策略:以最小的代价连续存储元素,由此而带来的访问元素的便利弥补了其存储代价;

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

21. string类型不支持以栈方式操纵容器;

22. 无论要求赋值多少个字符,标准库最多只能复制数目与string对象长度相等的字符;

23. stack适配器可以建立在vector、list或者deque容器之上,queue适配器只能建立在list容器上,priority_queue适配器只能建立在vector或deque容器上;

第十章 关联容器

1. 关联容器支持通过键来高效地查找和读取元素;

2. 关联容器不提供front、push_front、pop_front、back、push_back以及pop_back操作;

3. 要使用map对象,则必须包含map头文件;

4. 所有的比较函数必须在键类型上定义严格弱排序;

5. 在实际应用中,键类型必须定义<操作符,而且该操作符应能“正确地工作”;

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

7. map容器和set容器一样,存储的键必须唯一,而且不能修改(键的类型均为const);

8. multimap不支持下标运算;

第十一章 泛型算法

1. 使用泛型算法必须包含algorithm头文件;

2. 标准库还定义了一组泛化的算术算法,其命名习惯与泛型算法相同,使用这些算法必须包含numeric头文件;

3. 使用插入迭代器back_inserter的程序必须包含iterator头文件;

4. 通常,如果要以一个已存在的容器为副本创建新容器,更好的方法是直接用输入范围作为性构造容器的初始化式;

5. 算法不直接修改容器的大小,如果需要添加和删除元素,则必须使用容器操作;

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

7. 流迭代器值定义了最基本的迭代器操作:自增、解引用和赋值。此外,可比较两个istream迭代器是否相等;而ostream迭代器则不通过比较运算;

8. 流迭代器不能创建反向迭代器;

9. 需要低级类别迭代器的地方,可以使用任意一种更高级的迭代器;

第三部分类和数据抽象

第十二章 类

1. 将关键字const家在形参表之后,就可以将成员函数声明为常量:

double avg_price()const;

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

2. 类背后蕴涵的基本思想是数据抽象和封装;

3. 在const成员函数中,this的类型是一个指向const类类型对象的const指针。既不能改变this所指向的对象,也不能改变this所保存的地址;

4. 不能从const成员函数返回指向类对象的普通引用。Const成员函数只能返回*this作为一个const引用;

5. 可以通过声明为mutable来实现对类的数据成员的修改(甚至在const成员函数内),将关键字mutable放在成员声明之前:

mutable size_t access_ctr;

6. 可变数据成员永远都不能为const,甚至当它是const对象的成员时也如此,因此const成员函数可以改变mutable成员;

7. 即使两个类具有完全相同的成员列表,它们也是不同的类型。每个类的成员不同于任何其他类(或任何其他作用域)的成员;

8. 在类作用域之外,成员只能通过对象或指针分别使用成员访问操作符 . 或->来访问;

9. 出现在类的定义体之外的成员定义必须指明成员出现在那个类中:

double Sales_item::avg_price()const

{??}

10. 在定义于类外部的成员函数中,形参表和成员函数体出现在成员名之后,这些都是在类作用域中定义,所以可以不用限定而引用其他成员;

11. 返回类型出现在成员名字前面,如果函数在类定义体之外定义,则用于返回类型的名字在类作用域之外,如果返回类型使用由类定义的类型,则必须使用完全限定名;

12. 类定义实际上式在两个阶段中处理:

首先,编译成员声明;

只有在所有成员出现之后,才编译它们的定义本身;

13. 类成员定义中的查找:

首先检查成员函数局部作用域中的声明;

如果在成员函数中找不到该名字的声明,则检查对所有类成员的声明;

如果在类中找不到该名字的声明,则检查在此成员函数定义之前的作用域中出现的声明;

14. 使用相同名字来表示形参和成员,可能导致类的成员被屏蔽,但是仍然可以通过用类名来限定成员名或显式使用this指针使用它;

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

16. 省略初始化列表并在构造函数的函数体内对数据成员赋值是合法的;

17. 没有默认构造函数的类类型成员,以及const或引用类型的成员,都必须在构造函数初始化列表中进行初始化;

18. 成员被初始化的次序就是定义成员的次序;

19. 内置和复合类型的成员,如指针和数组,只对定义在全局作用域中的对象初始化;

20. 使用默认构造函数定义一个对象的正确方式是去掉最后的空括号:

sales_item myobj(); //error ,defines a function, not an object

sales_item myob ; // ok

21. 可以通过将构造函数声明为explicit,来防止在需要隐式转换的上下文中使用构造函数;

22. explicit关键字只能用于类内部的构造函数声明上,在类的定义体外部所做的定义上不再重复它;

23. 友元可以使普通的非成员函数,或前面定义的其他类的成员函数,或整个类。将一个类设为友元,友元类的所有成员函数后可以访问授予友元关系的那个类的非公有成员;

24. 类必须将重载函数集中每一个希望设为友元的函数都声明为友元;

25. 可以通过作用域操作符从类直接调用static成员,或者通过对象、引用或指向该类类型对象的指针间接调用;

26. 类成员函数可以不用作用域操作符来引用类的static成员;

第十三章 复制控制

1. 复制构造函数具有单个形参,该形参(常用const修饰)是对该类类型的引用,当定义一个新对象并用一个同类型的对象对它进行初始化时,将显式使用复制构造函数,当将该类型的对象传递给函数或从函数返回该类型的对象时,将隐式使用复制构造函数;

2. 不管类是否定义了自己的析构函数,编译器都自动执行类中非static数据成员的析构函数;

3. 不能对IO类型的对象使用复制初始化;

4. 当形参或返回值为类类型时,有复制构造函数进行赋值;

5. 即使定义了其他构造函数,也会合成赋值构造函数,合成复制构造函数的行为时,执行逐个成员初始化,将新对象初始化为原对象的副本;

6. 只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义复制构造函数,也可以复制;

7. 为了防止赋值,类必须显式声明其复制构造函数为private,然而,类的友元和成员仍可进行赋值,如果想要连友元和成员中的复制也禁止,就可以声明一个private复制构造函数但不对其定义;

8. 一般来说,最好显式或隐式定义默认构造函数和复制构造函数。只有不存在其他构造函数时才合成默认构造函数。如果定义了复制构造函数,也必须定义默认构造函数;

9. 如果类需要析构函数,则它也需要赋值操作符和复制构造函数;

10. 析构函数没有返回值,没有形参,也不能进行重载;

11. 编写自己的复制构造函数时,必须显式复制需要复制的任意成员。显式定义的复制构造函数不会进行任何自动复制;

第十四章 重载操作符与转换

1. 不能通过连接其他合法符号来创建任何新的操作符;

2. 用于内置类型的操作符,其含义不能改变,也不能为任何内置类型定义额外的新的操作符;

3. 操作符的优先级、结合性或操作数数目不能改变;

4. 重载逻辑操作符不再具备短路求值的特性;

5. 输入操作符必须处理错误和文件结束的可能性;

6. 一般而言,赋值操作符与复合赋值操作符应返回左操作数的引用;

7. 普通重载不能区别所定义的是前缀式操作符,为了解决这个问题,后缀式操作符函数接受一个额外的(即,无用的)int形参,使用后缀式操作符时,编译器提供0作为这个形参的实参;

CheckedPtr& CheckedPtr::operator--(); //prefix operators

CheckedPtr& CheckedPtr::operator--(int); //postfix operators

8. 可以为类类型的对象重载函数调用操作符,一般为表示操作的类重载调用操作符; struct absint{

int operator()(int val){

return val<0 ?-val :val;

}

};

9. 标准库提供了一组函数适配器,分为绑定器(bind1st 和bind2nd)和求反器(not1和not2):

bind1st将给定值绑定到二元函数对象的第一个实参,bind2nd将给定值绑定到二元函数对象的第二个实参;

not1将一元函数对象的真值求反,not2将二元函数的对象的真值求反;

10. 转换操作符定义将类类型值转变为其他类型值的转换,转换操作符在类定义体内声明,必须是成员函数,并且形参表必须为空。采用如下通用形式:

operator type();

这里type表示内置类型名、类类型名或由类型别名所定义的名字。对任何可作为函数返回类型的类型(除了void之外)都可以定义转换函数。一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的;

11. 虽然转换函数不能指定返回类型,但是每个转换函数必须显式返回一个指定类型的值;

12. 转换函数一般不应该改变被转换对象,因此转换操作符通常应定义为const成员;

13. 类类型转换之后不能再跟另一个类类型转换,如果需要多个类类型转换,则代码将出错;

14. 既为算术类型提供转换函数,又为同一类类型提供重载操作符,可能会导致重载操作符和内置操作符之间的二义性;

第四部分面向对象编程与泛型编程

第十五章 面向对象编程

1. 在C++中,多态性仅用于通过继承而相关联的类型的引用和指针;

2. 除了构造函数以外,任意非static成员函数都可以是虚函数。保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上;

3. protected成员不能被类的用户访问,但可被类的派生类访问;

4. 派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限;

5. 派生类的虚函数可以返回基类函数所返回类型的派生类的引用或指针;

6. 一旦函数在基类中声明为虚函数,它就一直为虚函数,派生类无法改变该函数为虚函数的这一事实;

7. 派生类对象由多个部分组成:派生类本身定义的(非static)成员加上由基类(非static)成员组成的子对象;

8. C++语言不要求编译器将对象的基类部分和派生部分连续排列;

9. 用作基类的类必须是已定义的的;

10. 继承的分类:

如果是公用继承,基类成员保持自己的访问级别:基类的public成员为派生类的public成员,基类的protected成员为派生类的protected成员;

如果是受保护继承,基类的public和protected成员在派生类中为protected成员; 如果是私有继承,基类的所有成员在派生类中为private成员;

11. struct定义的类和class定义的类唯一的不同知识默认成员的保护级别和默认的派生保护级别,struct默认的具有public继承,而class则具有private继承;

12. 友元可以访问类的private和protected数据;

13. 友元关系不能继承,基类友元关系对派生类的成员没有特殊访问权限,如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类;

14. 一般可以使用派生类型的对象对基类对象进行赋值或初始化;

15. 对基类对象进行赋值和初始化,实际上是在调用函数:初始化时定义构造函数,赋值时调用赋值操作符;

16. 如果是public继承,则用户代码和后代类都可以使用派生类到基类的转换。如果类是使用private或protected继承派生的,则用户代码不能将派生类对象转换为基类对象。如果是private继承,则从private继承类派生的类不能转换为基类。如果是protected继承,则后续派生类的成员可以转换为基类类型;

17. 基类对象只能是基类对象,它不能包含派生类型的对象;

18. 当构造、复制、赋值和撤销派生类型对象时,也会构造、复制、赋值和撤销这些基类子对象;

19. 派生类的合成默认构造函数除了初始化派生类的数据成员之外,它还初始化派生类对象的基类部分;

20. 派生类构造函数通过将基类包含在构造函数初始化列表中来间接初始化继承成员;

21. 派生类析构函数不负责撤销基类对象的成员;

22. 与基类成员同名的派生类成员将屏蔽对基类成员的直接访问,但仍可使用作用域操作符访问被屏蔽的基类成员;

23. 在基类和派生类中使用同一个名字的成员函数,其行为与数据成员一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽;

24. 局部作用域中声明的函数不会重载全局作用域中定义的函数,同样,派生类中定义的函数也不能重载基类中定义的成员。通过派生类对象调用函数时,实参必须与派生类中定义的版本相匹配,只有在派生类根本没有定义该函数时,才考虑基类函数;

25. 含有或继承一个或多个纯虚函数的类是抽象基类。除了作为抽象基类的派生类的对象的组成部分,不能创建抽象类型的对象;

第十六章 模板与泛型编程

1. 模板定义以关键字template开始,后接模板形参表,模板形参表使用尖括号括住的一个或多个模板形参的列表,形参之间以逗号分隔;

2. 模板形参表不能为空;

3. 模板形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参;

4. 使用函数模板时,编译器会推断哪个(或哪些)模板实参绑定到模板形参。一旦编译器确定了实际的模板实参,就称它实例化了函数模板的一个实例;

5. 与全局作用域中声明的对象、函数或类型同名的模板形参会屏蔽全局名字;

6. 用作模板形参的名字不能在模板内重用,模板形参的名字只能在同一模板形参表中使用一次;

7. 模板形参的名字可以在不同模板中重用;

8. 每个模板类型形参前面必须带上关键字class或typename,每个非类型形参前面必须带上类型名字,省略关键字或类型说明符是错误的;

9. 编写泛型代码的两个重要原则:

模板的形参是const引用;

函数体中的测试只用<比较;

10. 模板编译模型分为包含编译模型和分别编译模型两种;

11. export关键字能够指明给定的定义可能会需要在其他文件中产生实例化;

12. 类模板成员函数的定义具有如下形式:

必须以关键字template开头,后接类的模板形参表;

必须指出它是哪个类的成员;

类名必须包含其模板形参;

example:template <class T> ret-type(返回类型)Queue<T> ::member-name;

13. 在实例化类模板成员函数的时候,编译器不执行模板形参推断,相反,类模板成员函数的模板形参由调用该函数的对象的类型确定;

14. 类模板成员函数只有为程序所用才进行实例化,如果某函数从未使用,则不会实例化该成员函数;

15. 非类型模板实参必须是编译时常量表达式;

16. 在类模板中可以出现三种友元声明:

普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数;

类模板或函数模板的友元声明,授予对友元所有实例的访问权;

只授予对类模板或函数模板的特定实例的访问权的友元声明;

17. 模板特化:一个或多个模板形参的实际类型或实际值是指定的,特化的形式如下:

关键字template后面接一对空的尖括号(< >);

再接模板名和一对尖括号,尖括号中指定这个特化定义的模板形参; 函数形参表和函数体;

18. 对具有同一模板实参集的同一模板,程序不能既有显式特化又有实例化;

19. 特化出现在对该模板实力的调用之后是错误的;

(完)

更多相关推荐:
Dreamweaver的个人总结

个人总结学习Dreamweaver的这一个学期张老师讲了Dreamweaver知识和基本的PHP知识让我受益匪浅自己能够做一个小型的静态网页计算机知识是博大精深的它需要不断的学习来解决现实里的实际问题Adobe...

Dreamweaver网页制作技巧心得体会

Dreamweaver网页制作技巧心得体会熟悉网页设计的网友就知道,调用Style的方法很多,我们可以单击鼠标右键选择CustonStyle来调用Style标准,也可以在状态栏中的元素列表上单击右键来调用Sty…

Dreamweaver课程总结

Dreamweaver课程总结Web静态页面与浏览器基础知识:web静态页面:web静态页面是指在浏览器显示出来的一系列的文字和各种的表格图片的集合。web静态页面具有的优点是:1.相应快。在同等条件下。一个静…

Dreamweaver课程总结

第一章网页设计基础一TCPIP协议传输控制协议互联网络协议TCP和IP可以单独使用但经常是协同工作互相补充简单地说IP提供了数据传输的灵活性TCP提供了数据传输的可靠性二Internet采用一种唯一通用的地址格...

dreamweaver实验报告

实验报告课程名称指导教师学院专业班级学生姓名学号一实验目的和要求1熟悉Dreamweaver操作界面文档和本地站点的创建2练习使用Dreamweaver编辑网页二实验原理掌握Dreamweaver的操作环境利用...

Dreamweaver网页设计_实训报告

广播电视大学实训报告书一说明1浅灰色部分由学生填写2白色部分为教师判分用3本报告与学生实际作品相关联实训报告书二说明1浅灰色部分由学生填写2白色部分为教师判分用3本报告与学生实际作品相关联实训报告书三说明1浅灰...

Dreamweaver实验报告 - 副本

实验报告教技1101班1103014032苏永吉一实验目的要求1熟悉Dreamweaver的操作界面能够创建站点和文档利用其基本功能进行简单的编辑操作2能够使用Dreamweaver软件制作简单的网页二实验仪器...

安装Dreamweaver CS3 的心得

安装DreamweaverCS3的心得最近在应聘网络编辑这个职位一直没有接到面试的电话说实话有点烦大学里做的东西都找不到了所想弄点实在的东西给未来的东家看看但自己现在也没电脑于是就准备在舍友的先安上用着这才发现...

CorelDRAW_学习心得

CorelDRAW学习心得CorelDraw主要用途在于平面广告设计商标设计产品包装设计艺术图形创作漫画创作等对于产设的同学来说coreldraw是一个很好的也是必须熟练掌握的二维软件虽然学习的时间很短但通过两...

CorelDraw学习心得1

CorelDraw学习心得CorelDraw主要用途在于平面广告设计商标设计产品包装设计艺术图形创作漫画创作等在我所在的工作岗位上只要会用基本图形的绘制和文字即可所以在这里我着重介绍下我对于基本图形绘制和文字的...

Coreldraw学期工作总结

Coreldraw学期工作总结时光流逝转眼间一学期的工作又结束了就教学工作而言这学期推行项目教学法大量的计算机课来迅速提升学生的计算机能力CORELDRAW从四月中旬开课以来经过这两个月的强化学习学生已经能自如...

CorelDraw学习心得2

CorelDraw学习心得2Coreldraw绘图实际系统集合了图象编辑图象抓取位图转换动画制作等一系列应用程序构成了一个高级图形设计和编辑出版软件包目前被广泛应用于平面设计包装装潢彩色出版与多媒体制作等诸多领...

dreamweaver学习心得(12篇)