高质量c++编程读书笔记
4+3+2+2+2+2+5+5+2+5+2 strcpy函数的原型: assert((src != NULL) && (dst != NULL)); char *address = dst; while ((*dst++ = *src++) !=
‘\0’)
NULL; return address;
疑问1: // 相加函数,如果没有 friend 修饰则只许有一个右侧参数 friend String operate+( const String &s1, const String &s2); 疑问2: 6-2-2 要点1: 6-3-26.6 引用与指针的比较 要点2:引用和指针 (1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。 (2)不能有 NULL 引用,引用必须与合法的存储单元关联(指针则可以是 NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变指的对象)。 要点3: 不论两个 Print
函数的参数是否不同,如果类的某个成员函数要调用全 局函数 Print,为了与成员函数 Print 区别,全局函数被调用时应加‘::’标志。
如 ::Print(…); // 表示 Print 是全局函数而非成员函数 要点4:
8.2.成员函数的重载/覆盖/隐藏 成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有 virtual 关键字。
令人迷惑的隐藏规则
1.如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字, 基类的函数将被隐藏(注意别与重载混淆)。
2.如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字, 此时,基类的函数被隐藏(注意别与覆盖混淆)。
要点5: 第8章 c++函数的高级特性 对比于c语言的函数,c++增加了:
1.重载
2.内联
3.const
4.virtual 四种新机制。 重载和内联机制既可用于全局函数也可用于类的成员函数 const与virtual机制仅用于类的成员函数
c++语言采用重载机制的理由
1.在c++程序中,可以将语义,功能相似的几个函数用同一个名字表示, 即函数重载,这样便于记忆,提高了函数的易用性.
2.类的构造函数需要重载机制,因为c++规定构造函数与类同名。
要点6: 并不是两个函数的名字相同就能构成重载 全局函数和类的成员函数同名不算重载,因为函数的作用域不同
要点7:
8.1.3.当心隐式类型转换导致重载函数产生二义性
疑问3: 如果派生类继承了多个基类(包含了函数名字相同的函数) 那派生类怎么区分调用的是哪一个基类8.3 参数的缺省值 [root@192 learn_cpp]# vim output.cpp [root@192 learn_cpp]# pwd /home/zhusy/learn_cpp
要点8
8.5.1 用内联取代宏代码
8.5.2 内联函数的编程风格
1.inline是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。
2.定义在类声明之中的成员函数将自动地成为内联函数,例如: class A { public: void Foo(int x,int y){…} //自动地成为内联函数 }
3.如果函数体内的代码比较长,使用内两将导致内存消耗代价较高
4.如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大
要点9 第九章 类的构造函数、析构函数与赋值函数 每个类只用一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数, 其他的称为普通构造函数)。
疑问4:
9.2 构造函数的初始化表 ???如果类存在继承关系,派生类必须在其初始化表里调用基类的构造函数. 疑问5: ??? 9.5 不要轻视拷贝构造函数与赋值函数 Big-Three
要点10
10.1 继承 若在逻辑上B是A的“一种”,并且A的所有功能和属性对B而言都有意义,则允许 B继承A的功能和属性。
10.2 组合 若在逻辑上A是B的“一部分”(a part of),则不允许B从A派生,而是要用A和其它东西 组合出B
要点11
11.1.1 用const修饰函数的参数
1.const只能修饰输入参数
2.如果输入参数采用”指针传递“,那么加const修饰可以防止意外地改动该指针,起到保护作用
3.如果输入参数采用”值传递“,由于函数将自动产生临时变量用于复制参数,该输入参数本来就 无需保护,所以不要加const修饰
4.对于非内部数据类型的参数而言,像void Func(A a)这样声明的函数注定效率比较低。因为函数 体内将产生A类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。
总结:
1.对于非内部数据类型的输入参数,应该将”值传递“的方式改为”const 引用传递“,目的是提高 效率。例如将void Func(A a) 改为void Func(const A &a).
2.对于内部数据类型的输入参数,不要将”值传递“的方式改为”const引用传递“。否则既达不到提高 效率的目的,又降低了函数的可理解性。例如void Func(int x)不应该改为void Func(const int &x).
要点12
11.1.2 用const修饰函数的返回值
1.如果给以”指针传递“方式的函数返回值加const修饰,那么函数的返回值(即指针)的内容不能被修改, 该返回值只能被赋给加const修饰的同类型的指针 例如函数 const char *GetString(void);
如下语句将出现编译错误: char *str =GetString(); 正确的用法是 const char *str =
GetString();
2.如果函数返回值采用”值传递方式“,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有 任何价值。
3.函数返回值采用”引用传递“的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。