1. 在类内部定义的函数默觉得inline,内联函数应该在头文件里定义,由于其定义对编译器必须是可见的,以便编译器可以在调用点内联展开该函数的代码。

此时,仅有函数原型是不够的。

2.assert

3.异常

4.因为流对象不能复制。因此不能存储在容器中;因为流不能复制。因此形參或返回类型也不能为流类型,必须用指针或引用。对IO对象的读写会改变它的状态,因此引用必须是非const的。

5.假设须要重用文件流读写多个文件,必须在读还有一个文件之前调用clear清除该流的状态。

6.前向声明。

在声明之后。定义之前。类是一个不全然类型。即已知它是一个类型,但不知道包括哪些成员。

不全然类型仅仅能以有限方式使用。

不能定义该类型的对象。不全然类型仅仅能用于定义指向该类型的指针和引用,或者用于声明(而不是定义)使用该类型作为形參类型或返回类型的函数。

在创建类的对象之前。必须完整地定义该类。必须定义类,而不仅仅是声明类,这样,编译器就会给类的对象预定对应的存储空间。相同地,在使用引用或指针范文类的成员之前,必须定义类。

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

8.引用全局变量

int height;
void dummy(int height)
{
::height = 1;
}

函数中设定全局变量height为1而不是參数height为1.

9.必须对不论什么const或引用类型成员以及没有默认构造函数的类类型的不论什么成员使用初始化式。

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

11.实际上,假设定义了其它构造函数,则提供一个默认构造函数差点儿总是对的。通常在默认构造函数中给成员提供的初始值应该指出该对象时“空”的。

12.友元不是授予友元关系的那个类的成员,所以它们不受其声明出现部分的訪问控制影响。通常。将友元声明成组地放在类定义的開始或结尾是个好主意。友元能够是普通的非成员函数,或前面定义的其它类的成员函数。或整个类。

13.static函数没有this指针,不是不论什么对象的组成部分,不能声明为const。不能声明为虚函数。

14.static数据成员必须在类定义体的外部定义

15.拷贝构造函数可用于初始化顺序容器中的元素,如

vector<string> svec(5);

编译器首先使用string默认构造函数创建一个暂时值来初始化svec,然后使用拷贝构造函数将暂时值拷贝到svec的每一个元素。

16.为了防止复制,类必须显式声明其拷贝构造函数为private。假设想要连友元和成员的复制也禁止。就能够声明一个private拷贝构造函数但不正确其定义。这样在链接时导致错误。

17.不同意复制的类对象仅仅能作为引用传递给函数或从函数返回。它们也不能用作容器的元素。

18.容器中的元素总是依照逆序撤销,先撤销下标为size()-1的元素。最后是下标为0的元素。

19.三法则:指的是假设须要析构函数,则也须要赋值操作符和拷贝构造函数。

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

21.析构函数没有返回值,没有形參。由于不能指定不论什么形參,所以不能重载析构函数。尽管一个类能够定义多个构造函数,但仅仅能提供一个析构函数。应用于类的全部对象。

22.析构函数与拷贝构造函数或赋值操作符之间的一个重要差别是,即使我们编写了自己的析构函数,合成析构函数仍然执行。如我们编写了一个空的析构函数。则类的各成员还能够被合成析构函数撤销。

合成析构函数在自己定义析构函数之后执行。

23.大多数C++类採用下面三种方法之中的一个管理指针成员:

(1)指针成员採取常规指针型行为。这种类具有指针的全部缺陷但无需特殊的复制控制。

(2)类可以实现所谓的“智能指针”行为。

指针所指向的对象是共享的。但类可以防止悬垂指针。

(3)类採取值型行为。

指针所指向的对象时唯一的,由每一个类对象独立管理。

24.不能重载的操作符

::     .*    .    ?

:

25.重载操作符必须具有至少一个类类型或枚举类型的操作数。这条规则强制重载操作符不能又一次定义用于内置类型对象的操作符含义。

26.操作符的优先级、结合性或操作数数目不能改变。除了函数调用操作符operator()之外,重载操作符时使用默认实參是非法的。

27.作为类成员的重载函数。形參看起来比操作数少1.作为成员函数的操作符有一个隐含的this形參,限定为第一个操作数。

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

28.重载逗号、取地址、逻辑与、逻辑或等操作符通常不是好做法。这些操作符具有实用的含义,假设我们定义了自己的版本号,就不能使用这些内置含义。

29.当一个重载操作符含义不明显时。给操作取一个名字更好。对于非常少用的操作,使用命名函数通常比用操作符更好。假设不是普通操作,没有必要为简洁而使用操作符。

30.管理容器键类型和顺序容器的类型应定义==和<操作符,理由是很多算法假定这些操作符存在。比如sort算法使用<操作符。find算法使用==操作符。

31.类定义下标操作符时。一般须要定义两个版本号:一个为非const成员并返回引用,还有一个为const成员并返回const引用。

32.类型转换函数必须是成员函数,不能指定返回类型,而且形參表必须为空。尽管转换函数不能指定返回类型,可是每一个转换函数必须显式返回一个指定类型的值。比如,operator int返回一个int值。转换函数一般不应该改变被转换的对象。

因此,转换操作符通常应定义为const成员。

33.类类型转换之后不能再跟还有一个类类型转换。假设须要多个类类型转换,则代码将出错。

34.派生类仅仅能通过派生类对象訪问其基类的protected成员。派生类对其基类类型对象的protected成员没有特殊訪问权限。

35.派生类虚函数调用基类版本号时。必须显式使用作用域操作符。假设派生类函数忽略了这样做,则函数调用会在执行时确定而且将是一个自身调用,从而导致无穷递归。

36.private继承时能够在派生类的public部分使用using Base::XX的形式。使得基类的私有成员能够被用户訪问。

37.使用class保留字定义的派生类默认具有private继承,而用struct保留字定义的类默认具有public继承。

38.友元关系不能继承。基类的友元对派生类的成员没有特殊訪问权限。假设基类被授予友元关系,则仅仅有基类具有特殊訪问权限,该基类的派生类不能訪问授予友元关系的类。

39.假设基类定义了static成员,则整个继承层次中仅仅有一个这种成员。不管从基类派生出多少个派生类,每一个static成员仅仅有一个实例。

40.构造函数仅仅能初始化其直接基类的原因是每一个类都定义了自己的接口。派生类构造函数不能初始化基类的成员且不应该对其基类成员赋值。

41.与构造函数不同,派生类析构函数不负责撤销基类对象的成员,编译器总是显式调用派生类对象基类部分的析构函数。每一个析构函数仅仅负责清楚自己的成员。

42.即使没有工作要做。继承层次的根类也应该定义一个虚析构函数。

43.在复制控制中,仅仅有析构函数能够定义为虚函数,构造函数不能定义为虚函数。构造函数是在对象全然构造之前执行的。在构造函数执行的时候,对象的动态类型还不完整。将赋值操作符定义为虚函数将在派生类中定义一个參数为基类对象的operator=,与派生类中赋值操作符不符合。因此,将类的赋值操作符定义为虚函数会令人混淆,并且不会有什么用处。

44.假设在构造函数或析构函数中调用虚函数。则执行的是为构造函数或析构函数自身定义类型的版本号。

45.在继承情况下,派生类的作用域嵌套在基类作用域中。

46.对象、引用或指针的静态类型决定了对象可以完毕的行为。甚至当静态类型和动态类型可能不同的时候。就像使用基类类型的引用或指针时可能发生的,静态类型仍然决定着可以使用什么成员。

47.在派生类作用域中派生类成员函数将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽。

48.假设派生类想通过自身类型使用全部重载版本号,则派生类必需要么重定义全部重载版本号,要么一个也不重定义。

若不想重定义全部,能够为重载成员提供using声明。一个using声明仅仅能指定一个名字。不能指定形參表。因此能够将该函数的全部重载实例加到派生类的作用域。

49.虚函数必须在基类和派生类中拥有同一原型。

50.C++ primer P501。派生类的同名函数可能会将基类的虚函数屏蔽。进而无法通过派生类对象调用,能够通过指向派生类对象的基类引用或指针调用。

51.由于派生类对象在赋值给基类对象时会被“切掉”。所以容器与通过继承相关的类型不能非常好地融合。

52.面向对象编程所依赖的多态性称为执行时多态性。泛型编程所依赖的多态性称为编译时多态性或參数式多态性。

53.用作模板形參的名字不能在模板内部重用,这一限制还意味着模板形參的名字仅仅能在同一模板形參中使用一次。

54.在模板成员名前加上keywordtypename作为前缀,能够告诉编译器将成员当作类型。

55.数组形參能够声明为数组的引用。假设形參是数组的引用,编译器不会将数组实參转化为指针,而是传递数组的引用本身。在这样的情况去,数组大小成为形參和实參类型的一部分。编译器检查数组实參的大小与形參的大小是否匹配。

56.显式模板实參从左至右与相应模板形參相匹配。

57.当编译器看到模板定义的时候,它不马上产生代码。仅仅有在看到用到模板时。如调用了函数模板或调用了类模板的对象的时候,编译器才产生特定类型的模板实例。

58.在包括编译模型中。编译器必须看到用到的全部模板的定义。

59.非类型模板实參必须是编译时常量表达式。

60.特化和部分特化(偏特化)能够具有与通用类模板全然不同的成员集合。

61.函数模板能够重载:能够定义有同样名字但形參数目或类型不同的多个函数模板。也能够定义与函数模板有同样名字的普通非模板函数。

62.异常对象通过复制被抛出表达式的结果创建,该结果必须是能够复制的类型。

63.抛出指针一般是个坏主意:抛出指针要求在相应处理代码存在的随意地方存在所指向的对象。

64.栈展开期间,释放局部对象所用的内存并执行类类型局部对象的析构函数。

65.在为某个异常进行栈展开的时候,析构函数假设又抛出自己的未经处理的还有一个异常,将会导致调用标准库terminate函数。一般而言,terminate函数将调用abort函数,强制从整个程序非正常退出。

66.与析构函数不同,构造函数内部所做的事情常常会抛出异常,因此要保证适当地撤销已构造的成员。

67.假设找不到匹配的catch,程序就调用库函数terminate。

68.catch捕获的类型必须是已定义的,类型的前向声明不行。

69.通常,假设catch字句处理因继承而相关的类型的异常,它就应该将自己的形參定义为引用。

70.假设catch(...)与其它catch子句结合使用。它必须是最后一个。否则。不论什么跟在它后面的catch子句都将不能被匹配。

71.构造函数要处理来自构造函数初始化式的异常,唯一的方法是将构造函数编写为函数測试块。

72.异常安全指即使发生异常程序也能正常操作,即被分配的不论什么资源都适当地释放。通过定义一个类来封装资源的分配和释放,能够保证释放资源。这一技术常称为“资源分配即初始化”,简称RAII。

应该设计资源管理类。以便构造函数分配资源而析构函数释放资源。

73.autoi_ptr仅仅能用于管理从new返回的一个对象。它不能管理动态分配的数组。

当auto_ptr被复制或赋值的时候,有不平常的行为,因此,不能将auto_ptr存储在标准库容器类型中。auto_ptr的复制和赋值改变右操作数,因此,赋值的左右操作数必须都是可改动的左值。

74.应该仅仅用get询问auto_ptr对象或者使用返回的指针值。不能用get作为创建其它auto_ptr对象的实參。

75.auto_ptr对象与内置指针的还有一个差别是,不能直接将一个地址9或者其它指针)赋给auto_ptr对象

76.auto_ptr缺陷:

77.假设一个函数声明没有指定异常说明。则该函数能够抛出随意类型的异常。

78.在编译的时候,编译器不能也不会试图验证异常说明。假设函数抛出了没有在其异常说明中列出的异常,就调用标准库函数unexpected。

默认情况下,unexpected函数调用terminate函数,terminate函数通常会终止程序。

79.由于不能再编译时检查异常说明,异常说明的应用一般是有限的。异常说明实用的一种重要情况是。假设函数能够保证不会抛出不论什么异常,对函数的用户和编译器都有所帮助。

80.派生类虚函数异常说明必须与相应基类虚函数的异常说明相同严格,或者比后者更受限。这个限制保证,当使用指向基类类型的指针调用派生类虚函数的时候,派生类异常说明不会添加新的可抛出异常。

81.在用还有一指针初始化带异常说明的函数的指针。或者将后者赋值给函数地址的时候。两个指针的异常说明不必同样。可是,源指针的异常说明必须至少与目标指针的一样严格。

82.命名空间能够在全局作用域或其它作用域内部定义。但不能在函数或类内部定义。

命名空间作用域不能以分号结束。

83.命名空间能够在几个部分中定义。命名空间由它的分离定义部分的总和构成。命名空间是累积的。

84.未命名的命名空间与其它命名空间不同。未命名的命名空间的定义局部于特定文件,从不跨越多个文本文件。

在命名空间引入C++之前,採用static声明局部于文件的名字。

85.假设头文件定义了未命名的命名空间,那么,在每一个包括该头文件的文件里,该命名空间中的名字将定义不同的局部实体。

86.接受类类型形參(或类类型指针及引用形參)的函数(包含重载操作符),以及与类本身定义在同一命名空间中函数(包含重载操作符),在用类类型对象(或类类型的引用及指针)作为实參的时候是可见的。

87.为了提供命名空间中所定义模板的自己的特化。必须保证在包括原始模板定义的命名空间中定义特化。

88.在虚派生中,由最底层派生类的构造函数初始化虚基类。不管虚基类出如今继承层次中不论什么地方,总是在构造非虚基类之前构造虚基类。

89.sort、sort_heap排序默认使用less。为递增排序。make_heap默认使用less,为最大堆。大的在前,小的在后。。

90.模板函数是函数模板的一个实例。

91.函数不能偏特化。

92.除非我有一个好理由同意构造函数被用于隐式类型转换。否则我会把他声明为explicit。

93.

Widget w2 = w1; //调用copy构造函数,而非copy assignment运算符

泛型和面向对象C++的更多相关文章

  1. boost.asio源码剖析(五) ---- 泛型与面向对象的完美结合

    有人说C++是带类的C:有人说C++是面向对象编程语言:有人说C++是面向过程与面向对象结合的语言.类似的评论网上有很多,虽然正确,却片面,是断章取义之言. C++是实践的产物,C++并没有为了成为某 ...

  2. 使用泛型集合取代datatable作为返回值实现面向对象

    开会的时候,师父说.我们在机房重构时,尽量不要用datatable作为返回值.改用泛型集合的方式,这样能够实现真正的面向对象. 通过查资料和同学交流,把这个问题给攻克了. 对于泛型集合.我也有了一些认 ...

  3. [.net 面向对象编程基础] (1) 开篇

    [.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...

  4. [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)

    [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这 ...

  5. [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

    [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化 本节导读: 介绍JSON的结构,在JS中的使用.重点说明JSON如何在.N ...

  6. Java基础知识笔记(二:泛型和枚举)

    1.泛型 与面向对象的多态性相类似,应用泛型可以提高程序的复用性.与多态性不同的是,应用泛型可以减少数据的类型转换,从而提高代码的运行效率.泛型实际上是通过给类或接口增加类型参数实现的.不带泛型的类的 ...

  7. [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用

    [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...

  8. 麻省理工《C内存管理和C++面向对象编程》笔记---第一讲:认识C和内存管理

    最近一年都在用.net和Java,现在需要用C了.昨天看到博客园首页的麻省理工开放课程,就找来看看,正好复习一下.这门<C内存管理和C++面向对象编程>不是那种上来就变量,循环的千篇一律的 ...

  9. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

随机推荐

  1. Elasticsearch之CURL命令的UPDATE

    对于,Elasticsearch之CURL命令的UPDATE包括局部更新和全部更新.可以去看我写的另一篇博客. Elasticsearch之更新(全部更新和局部更新) 总结: ES全部更新,使用PUT ...

  2. OFDM同步算法之Park算法

    park算法代码 训练序列结构 T=[\(C\) \(D\) \(C^{*}\) \(D^{*}\)],其中C表示由长度为N/4的复伪随机序列PN,ifft变换得到的符号序列 \(C(n) = D(N ...

  3. EF code first Acceleration - CodeFirst 加速

    EntityFramework Code First 用起来很方便,可是有时感觉卡,就是有点慢.可以采用以下措施来加速一下,原来取出1万条记录并显示在Winform窗体上第一次需要1.9秒的时间,加速 ...

  4. CSS——层级

    层级问题:选中的盒子显示的效果并不完整,右边的边框并没有显示红色,原因是其右边的盒子压了它的边框. <!DOCTYPE html> <html lang="en" ...

  5. 【sqli-labs】 less54 GET -Challenge -Union -10 queries allowed -Variation1 (GET型 挑战 联合查询 只允许10次查询 变化1)

    尝试的次数只有10次 http://192.168.136.128/sqli-labs-master/Less-54/index.php?id=1' 单引号报错,错误信息没有显示 加注释符页面恢复正常 ...

  6. MFC TAB控件顺序

    在MFC中添加控件后,按Ctrl+d可以改变控件TAB顺序,怕自己忘了,一个神奇的东西,记下. 关于改变Tab顺序的方法有以下几种: 方法一:在动态创建控件的时候STYLE设置成为WS_CHILD|W ...

  7. xamarin.forms模拟rem动态大小值,实现屏幕适配

    开发app的时候,比较麻烦的地方,就是处理屏幕适配,比如文字设为12的大小,测试的时候,看得文字挺正常,可是,放到高分辨率设备一看,文字就变得特别小, 怎样实现随着分辨率变大或者变小,所有的size数 ...

  8. Java类及成员

    Java类及成员 类 类是对一类事物的的描述,是抽象的概念上的定义:类是创建对象的模板: public class TestClass { public static void main(String ...

  9. Python os模块和time模块 day4

    一.os模块 print(os.listdir(r'/Users/smh/Desktop/整理'))#os.listdir() 列出某个目录下面的文件夹/文件 print(os.path.isfile ...

  10. vue项目的路由配置

    方案一.在生成项目的时候就选择安装路由; 这个地方选择y即可; 生成项目之后在src目录下会有router文件夹,里面有index.js,并且里面已经存在一个helloWorld页面了,可以直接模仿着 ...