《高质量 C++/C 编程指南 》阅读笔记(三)
来源:互联网 发布:unreal 源码分析 编辑:程序博客网 时间:2024/05/24 01:50
《高质量 C++/C 编程指南 》阅读笔记(三)
C++函数的高级特性
1、对比于 C 语言的函数,C++增加了重载(overloaded)、内联(inline)、const 和 virtual四种新机制。其中重载和内联机制既可用于全局函数也可用于类的成员函数,const 与virtual 机制仅用于类的成员函数。
2、以只能靠参数而不能靠返回值类型的不同来区分重载函数。编译器根据参数为每个重载函数产生不同的内部标识符。
3、并不是两个函数的名字相同就能构成重载。全局函数和类的成员函数同名不算重载,因为函数的作用域不同。
4、重载与覆盖
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有 virtual 关键字。
5、本来仅仅区别重载与覆盖并不算困难,但是 C++的隐藏规则使问题复杂性陡然增加。这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
6、参数缺省值只能出现在函数的声明中,而不能出现在定义体中。、
7、在 C++语言中,可以用关键字 operator 加上运算符来表示函数,叫做运算符重载。
Complex operator +(const Complex &a, const Complex &b);
8、 运算符 规则
所有的一元运算符 建议重载为成员函数
= () [] -> 只能重载为成员函数
+= -= /= *= &= |= ~= %= >>= <<= 建议重载为成员函数
所有其它运算符 建议重载为全局函数
9、在 C++运算符集合中,有一些运算符是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。
(1)不能改变 C++内部数据类型(如 int,float 等)的运算符。
(2)不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。
(3)不能重载目前 C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。
(4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。
10、C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。
11、关键字 inline 必须与函数定义体放在一起才能使函数成为内联,仅将 inline 放在函数声明前面不起任何作用。所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。
12、定义在类声明之中的成员函数将自动地成为内联函数。
13、内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
类的构造函数、析构函数与赋值函数
1、 A(void); // 缺省的无参数构造函数
A(const A &a); // 缺省的拷贝构造函数
~A(void); // 缺省的析构函数
A & operate =(const A &a); // 缺省的赋值函数
2、 class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
3、构造函数与析构函数的另一个特别之处是没有返回值类型,这与返回值类型为 void 的函数不同。构造函数与析构函数的使命非常明确,就象出生与死亡,光
溜溜地来光溜溜地去。如果它们有返回值类型,那么编译器将不知所措。为了防止节外生枝,干脆规定没有返回值类型。
4、如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误。
5、拷贝构造函数和赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。
String a(“hello”);
String b(“world”);
String c = a; // 调用了拷贝构造函数,最好写成 c(a);
c = b; // 调用了赋值函数
6、基类的构造函数、析构函数、赋值函数都不能被派生类继承。如果类之间存在继承关系,在编写上述基本函数时应注意以下事项:
派生类的构造函数应在其初始化表里调用基类的构造函数。
基类与派生类的析构函数应该为虚(即加 virtual 关键字)。
- 《高质量 C++/C 编程指南 》阅读笔记(三)
- 《高质量 C++/C 编程指南 》阅读笔记(二)
- 《高质量 C++/C 编程指南 》阅读笔记(四)
- 高质量C/C++编程指南 阅读笔记(三)重载
- 高质量C++/C 编程指南 阅读笔记(一)编程规范
- 《高质量C++&C编程指南》笔记
- 《高质量C++C编程指南》笔记
- 高质量C++C编程指南笔记
- 高质量C++/C编程指南(三)
- 高质量C/C++编程指南 阅读笔记(二)内存管理
- 高质量C/C++编程指南 阅读笔记(五)类的继承与组合
- 《高质量C++/C编程指南(林锐)》学习笔记
- 阅读《高质量C++C编程指南》和《google_c++编程风格(高清版)》笔记
- 高质量C&C++编程指南---笔记
- 高质量C、C++编程指南 笔记
- 《高质量C/C++编程指南》笔记
- 高质量C/C++编程指南笔记
- 【C】【笔记】高质量C++编程指南
- rocketmq 安装配置出现NoClassDefFoundError的问题
- Treap树堆的基本模板(无讲解)
- B
- HDU 6108 小C的倍数问题 (数论 2017百度之星初赛A第1题)
- xcode 删除复制某一行 快捷键
- 《高质量 C++/C 编程指南 》阅读笔记(三)
- Tomcat出现Unloading class sun.reflect.GeneratedMethodAccessor216]解决方案
- 关于STL的一些笔记
- 500. Keyboard Row
- Address类型和Mapping 类型
- 解决apache配置php7时出现的Cannot load ../php-5.6.13/php5apache2_4.dll into server:
- 背包九讲第一讲-简单的0/1背包问题有感1.3
- 1526:宗教信仰(4.3算法之图论)
- JavaScript趣味编程--仿微信飞机大战游戏--1.画飞机