626 lines
10 KiB
Markdown
626 lines
10 KiB
Markdown
|
|
# 绪论
|
|||
|
|
|
|||
|
|
## 程序语言
|
|||
|
|
|
|||
|
|
- 机器语言
|
|||
|
|
- 0 、1组成
|
|||
|
|
- 汇编语言
|
|||
|
|
- 助记符组成
|
|||
|
|
- 直接操作寄存器
|
|||
|
|
- 高级语言
|
|||
|
|
- 接近自然语言
|
|||
|
|
- 屏蔽机器细节
|
|||
|
|
|
|||
|
|
## C++
|
|||
|
|
|
|||
|
|
1970 年 C ----> 1983 年 C with Class
|
|||
|
|
|
|||
|
|
### 特性
|
|||
|
|
|
|||
|
|
- 虚函数 、操作符重载
|
|||
|
|
- 多重继承 、模板
|
|||
|
|
- 异常处理 、 名字空间
|
|||
|
|
- RTTI
|
|||
|
|
|
|||
|
|
### 向下兼容
|
|||
|
|
|
|||
|
|
C++ = C + 不完全的面向对象
|
|||
|
|
|
|||
|
|
new 与 delete 内存泄漏
|
|||
|
|
|
|||
|
|
允许多继承,关系复杂
|
|||
|
|
|
|||
|
|
## 面向对象
|
|||
|
|
|
|||
|
|
- 数据 + 操作 = 对象
|
|||
|
|
- 抽象程度高
|
|||
|
|
|
|||
|
|
## 面向过程
|
|||
|
|
|
|||
|
|
- 函数的排列组合
|
|||
|
|
- 抽象程度低
|
|||
|
|
|
|||
|
|
## 信息
|
|||
|
|
|
|||
|
|
### 数字系统
|
|||
|
|
|
|||
|
|
- R 进制 转 十进制
|
|||
|
|
- 各位数字与它的权相乘,其积相加
|
|||
|
|
|
|||
|
|
- 十进制 转 R 进制
|
|||
|
|
- 整数 除R取余
|
|||
|
|
- 小数 乘R取整
|
|||
|
|
|
|||
|
|
- 10 = 012 = 0xA
|
|||
|
|
|
|||
|
|
### 数字编码
|
|||
|
|
|
|||
|
|
- 原码
|
|||
|
|
- 符号位 + 绝对值
|
|||
|
|
- q = +k 与 -k
|
|||
|
|
- 负号 0 正号 1
|
|||
|
|
- 反码
|
|||
|
|
- q = +k 与 M - k - 1
|
|||
|
|
- 负数的数字位取反
|
|||
|
|
- 补码
|
|||
|
|
- q = +k 与 M - K
|
|||
|
|
- 浮点数
|
|||
|
|
- 1 + 8+ 23
|
|||
|
|
- 1 + 11 + 52
|
|||
|
|
- 定点数
|
|||
|
|
|
|||
|
|
# 数据类型
|
|||
|
|
|
|||
|
|
## 数据初始化
|
|||
|
|
|
|||
|
|
p [ptr->data] class
|
|||
|
|
|
|||
|
|
*p [data] class
|
|||
|
|
|
|||
|
|
- 常量
|
|||
|
|
- 常量在定义时就必须赋初值
|
|||
|
|
- 常量指向的数据不可变
|
|||
|
|
- 指针
|
|||
|
|
- p 指向数据的地址
|
|||
|
|
- *p 取数据
|
|||
|
|
- 内置变量
|
|||
|
|
- 函数内未定义
|
|||
|
|
- 函数外为0
|
|||
|
|
- 类
|
|||
|
|
- 列表初始化
|
|||
|
|
- 圆括号初始化
|
|||
|
|
- 拷贝初始化
|
|||
|
|
- 直接初始化
|
|||
|
|
- 内置类型被初始化为0
|
|||
|
|
- 类类型由构造函数初始化
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
## 特殊类型
|
|||
|
|
|
|||
|
|
### 常量
|
|||
|
|
|
|||
|
|
声明时必须赋值 (指针除外)
|
|||
|
|
|
|||
|
|
不可以改变常量的值
|
|||
|
|
|
|||
|
|
const 定义后的内容不可变
|
|||
|
|
|
|||
|
|
const 常量指向 地址
|
|||
|
|
|
|||
|
|
宏常量指向文本
|
|||
|
|
|
|||
|
|
const float PI = 3.14;
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
//const 后的内容不可变
|
|||
|
|
const float PI = 3.14;
|
|||
|
|
int const radiu = 1;
|
|||
|
|
//XXX const int size; PI = 3.14159;
|
|||
|
|
|
|||
|
|
//常指针 *p1 不可变,p1可变
|
|||
|
|
int const *p1;
|
|||
|
|
//指针常量 p2 不可变 必须赋初值,*p2可变
|
|||
|
|
int i = 0;
|
|||
|
|
int * const p2 = &i;
|
|||
|
|
//常指针常量 指向常量的常指针
|
|||
|
|
const int * const p3 = &radiu;
|
|||
|
|
//常引用
|
|||
|
|
const int& p4 = radiu;
|
|||
|
|
|
|||
|
|
enum Weekday {SUN=7, MON=1, TUE=1, WED, THU, FRI, SAT};
|
|||
|
|
//const int SUN = 7;....
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
### 枚举
|
|||
|
|
|
|||
|
|
enum Weekday {SUN=7, MON=1, TUE=1, WED, THU, FRI, SAT};
|
|||
|
|
|
|||
|
|
常量的集合,默认为文件作用域
|
|||
|
|
|
|||
|
|
## 类型关键字
|
|||
|
|
|
|||
|
|
### 类型转换
|
|||
|
|
|
|||
|
|
- 类型转换操作符
|
|||
|
|
- const_cast
|
|||
|
|
- static_cast
|
|||
|
|
- dynamic_cast
|
|||
|
|
- reinterpret_cast
|
|||
|
|
|
|||
|
|
### typedef
|
|||
|
|
|
|||
|
|
为一个已有的数据类型另外命名-类型定义
|
|||
|
|
|
|||
|
|
typedef 已有类型名 新类型名表;
|
|||
|
|
|
|||
|
|
### auto decltype
|
|||
|
|
|
|||
|
|
decltype(i) j = 2;
|
|||
|
|
|
|||
|
|
### sizeof
|
|||
|
|
|
|||
|
|
- “类型名”所指定的类型所占的字节数
|
|||
|
|
- “表达式”的结果类型所占的字节数
|
|||
|
|
|
|||
|
|
由编译器推测,数组在定义内和参数有不同大小
|
|||
|
|
|
|||
|
|
先求类型,再求类型所占字节数
|
|||
|
|
|
|||
|
|
## 运算符
|
|||
|
|
|
|||
|
|
- =
|
|||
|
|
- a = 10
|
|||
|
|
- (a = 10 ) = 10
|
|||
|
|
- a = (a = 10)
|
|||
|
|
- ,
|
|||
|
|
- 表达式:a , b = b
|
|||
|
|
- 分隔符:int a, b
|
|||
|
|
- ++/--
|
|||
|
|
- i++ 与 ++i
|
|||
|
|
|
|||
|
|
# 函数
|
|||
|
|
|
|||
|
|
函数声明和函数原型
|
|||
|
|
|
|||
|
|
## 函数参数
|
|||
|
|
|
|||
|
|
### 值传递
|
|||
|
|
|
|||
|
|
单向传递,拷贝后和实参无关联
|
|||
|
|
|
|||
|
|
对象是值传递
|
|||
|
|
|
|||
|
|
### 引用传递
|
|||
|
|
|
|||
|
|
用于函数通信
|
|||
|
|
|
|||
|
|
节省开销
|
|||
|
|
|
|||
|
|
### 可变参数
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
void log_info(initializer_list<string> lst) {
|
|||
|
|
for (auto& info : lst)
|
|||
|
|
cout << info << ' ';
|
|||
|
|
cout << endl;
|
|||
|
|
}
|
|||
|
|
log_info({ "“Hello”", "”world”", "“!”" });
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 缺省参数
|
|||
|
|
|
|||
|
|
在函数声明中定义参数值
|
|||
|
|
|
|||
|
|
不可重复定义,没有声明就放函数原型中定义
|
|||
|
|
|
|||
|
|
函数缺省值必须位于最后
|
|||
|
|
|
|||
|
|
缺省参数不参与函数重载
|
|||
|
|
|
|||
|
|
## 内联函数
|
|||
|
|
|
|||
|
|
用来替代宏函数
|
|||
|
|
|
|||
|
|
用关键字 inline 修饰 函数
|
|||
|
|
|
|||
|
|
似乎对函数内容有限制
|
|||
|
|
|
|||
|
|
## 函数重载
|
|||
|
|
|
|||
|
|
相同作用域内声明相同的函数名
|
|||
|
|
|
|||
|
|
通过形参和名字来区分函数
|
|||
|
|
|
|||
|
|
const 修饰符也用于区分函数
|
|||
|
|
|
|||
|
|
# 类
|
|||
|
|
|
|||
|
|
## 特性
|
|||
|
|
|
|||
|
|
- 封装
|
|||
|
|
- 数据和函数封装成对象
|
|||
|
|
- 封装成员的访问权限
|
|||
|
|
- 继承
|
|||
|
|
- 多态
|
|||
|
|
|
|||
|
|
## 访问控制
|
|||
|
|
|
|||
|
|
### 访问控制符
|
|||
|
|
|
|||
|
|
class 默认访问控制是 private
|
|||
|
|
|
|||
|
|
struct 默认访问控制是 public
|
|||
|
|
|
|||
|
|
- public
|
|||
|
|
- 外部访问的接口
|
|||
|
|
- protected
|
|||
|
|
- 子类可访问
|
|||
|
|
- private
|
|||
|
|
- 只允许本类访问
|
|||
|
|
|
|||
|
|
### 可访问成员
|
|||
|
|
|
|||
|
|
不可访问的成员不可见
|
|||
|
|
|
|||
|
|
- 类内
|
|||
|
|
- 可直接使用成员名访问
|
|||
|
|
- 类外部
|
|||
|
|
- 对象名.成员名
|
|||
|
|
- 类名::成员名
|
|||
|
|
|
|||
|
|
## 静态标识
|
|||
|
|
|
|||
|
|
在 class 中声明的静态变量是全局变量,需要在类外定义。
|
|||
|
|
|
|||
|
|
静态成员函数只有静态成员变量可见
|
|||
|
|
|
|||
|
|
## 函数
|
|||
|
|
|
|||
|
|
在类的声明中定义函数原型
|
|||
|
|
|
|||
|
|
非静态函数中隐含this指针,指向自身对象
|
|||
|
|
|
|||
|
|
### 内联函数
|
|||
|
|
|
|||
|
|
类声明里的函数都是内联函数
|
|||
|
|
|
|||
|
|
### 构造函数
|
|||
|
|
|
|||
|
|
在对象创建时由系统自动调用
|
|||
|
|
|
|||
|
|
如果没有定义:
|
|||
|
|
|
|||
|
|
系统会自动创建一个参数为空的构造函数
|
|||
|
|
|
|||
|
|
函数名与类名相同 没有返回值
|
|||
|
|
|
|||
|
|
### 析构函数
|
|||
|
|
|
|||
|
|
若析构函数不是虚函数,系统自动调用当前类的析构函数,而调用不到子类的析构函数
|
|||
|
|
|
|||
|
|
虚函数会增加虚指针和虚函数表
|
|||
|
|
|
|||
|
|
在对象销毁时由系统自动调用自身析构以及成员对象析构
|
|||
|
|
|
|||
|
|
如果没有定义:
|
|||
|
|
|
|||
|
|
系统会自动创建一个参数为空的析构函数
|
|||
|
|
|
|||
|
|
函数名与类名相同 没有返回值
|
|||
|
|
|
|||
|
|
### 拷贝构造函数
|
|||
|
|
|
|||
|
|
形参为本类的对象引用
|
|||
|
|
|
|||
|
|
在对象赋值时系统会自动调用 (赋值的原理是拷贝构造函数)
|
|||
|
|
|
|||
|
|
如果没有定义:
|
|||
|
|
|
|||
|
|
系统会自动创建一个参数为空的拷贝构造函数
|
|||
|
|
|
|||
|
|
## 对象继承
|
|||
|
|
|
|||
|
|
对象 = 虚函数表指针 + 成员变量
|
|||
|
|
|
|||
|
|
子类对象 = 虚函数表指针 + 父类成员变量 + 子类成员变量
|
|||
|
|
|
|||
|
|
派生类继承了基类中的所有成员
|
|||
|
|
构造函数、析构函数、友元函数除外
|
|||
|
|
|
|||
|
|
### 继承方式
|
|||
|
|
|
|||
|
|
子类继承父类的 public 和 protected 成员
|
|||
|
|
|
|||
|
|
并且修改访问权限
|
|||
|
|
|
|||
|
|
新访问权限 = 继承方式 * 旧访问权限
|
|||
|
|
|
|||
|
|
- 公有继承
|
|||
|
|
- 继承后的成员的访问权限不变
|
|||
|
|
- 保护继承
|
|||
|
|
- 继承后父类的public成员变为protected成员
|
|||
|
|
- 私有继承
|
|||
|
|
- 继承后父类的public 、 protected成员变为private成员
|
|||
|
|
- 虚继承
|
|||
|
|
- 有对象组合改为指针组合,指针实例在对象的末尾的位置创建
|
|||
|
|
- 公共基类只有一份拷贝
|
|||
|
|
- (增加了虚表)
|
|||
|
|
|
|||
|
|
### 类型转换
|
|||
|
|
|
|||
|
|
子类可以替换父类
|
|||
|
|
|
|||
|
|
## 类和对象
|
|||
|
|
|
|||
|
|
### 前向引用声明
|
|||
|
|
|
|||
|
|
声明标识符
|
|||
|
|
|
|||
|
|
### 类声明
|
|||
|
|
|
|||
|
|
class 默认访问控制是 private
|
|||
|
|
|
|||
|
|
在类里定义数据成员和初值
|
|||
|
|
|
|||
|
|
在类的声明中定义函数原型和内联函数
|
|||
|
|
|
|||
|
|
### 对象构造
|
|||
|
|
|
|||
|
|
从下到上
|
|||
|
|
|
|||
|
|
构造组合对象{
|
|||
|
|
|
|||
|
|
父类对象:父类继承顺序
|
|||
|
|
|
|||
|
|
构造父类组合对象
|
|||
|
|
|
|||
|
|
属性对象:属性声明顺序
|
|||
|
|
|
|||
|
|
构造自身:把前面的对象组合起来
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
### 对象析构
|
|||
|
|
|
|||
|
|
和构造函数顺序相反
|
|||
|
|
|
|||
|
|
从上到下
|
|||
|
|
|
|||
|
|
# 多态性
|
|||
|
|
|
|||
|
|
发出同样的消息,被不同类型的对象接收,有可能导致完全不同的行为
|
|||
|
|
|
|||
|
|
一个接口,多种方法
|
|||
|
|
|
|||
|
|
## 实现方式
|
|||
|
|
|
|||
|
|
确定绑定的方法
|
|||
|
|
|
|||
|
|
**静态多态性**
|
|||
|
|
|
|||
|
|
在编译连接阶段就能完成绑定工作的情况
|
|||
|
|
|
|||
|
|
- 函数重载
|
|||
|
|
|
|||
|
|
- 模板
|
|||
|
|
|
|||
|
|
函数模板用来创建通用功能的函数,以支持多种不同形参
|
|||
|
|
进一步简化重载函数的函数体设计
|
|||
|
|
|
|||
|
|
- 运算符重载
|
|||
|
|
|
|||
|
|
- 后置 ++ 需要一个 int 参数
|
|||
|
|
|
|||
|
|
**动态多态性**
|
|||
|
|
|
|||
|
|
在程序运行阶段才能完成绑定工作的情况
|
|||
|
|
|
|||
|
|
- 虚函数
|
|||
|
|
- 函数重名覆盖是依据静态类型,编译器自动重载的
|
|||
|
|
- 对于动态类型,不能实现多态,需要虚函数
|
|||
|
|
- 虚函数是实现运行时多态性基础
|
|||
|
|
|
|||
|
|
### 多态的类型
|
|||
|
|
|
|||
|
|
- 重载多态
|
|||
|
|
|
|||
|
|
- 强制多态
|
|||
|
|
- 强制多态是指对变量进行强制类型转换,使其符合函数、操作的要求
|
|||
|
|
- 包含多态
|
|||
|
|
- 包含多态是类族中定义在不同类中的、同名函数的多态行为,通过虚函数实现
|
|||
|
|
- 参数多态
|
|||
|
|
- 参数多态与类模板相关联,在使用时必须指定实际的类型才能实例化
|
|||
|
|
|
|||
|
|
## 模板
|
|||
|
|
|
|||
|
|
### 函数模板
|
|||
|
|
|
|||
|
|
类型名可作为参数
|
|||
|
|
|
|||
|
|
编译器只检测<>内参数是否匹配
|
|||
|
|
|
|||
|
|
templateName<param1 , param2 ...>( params);
|
|||
|
|
|
|||
|
|
### 类模板
|
|||
|
|
|
|||
|
|
- 使用类模板可以为类声明一种模式,使得类中的
|
|||
|
|
- 数据成员
|
|||
|
|
- 成员函数的参数
|
|||
|
|
- 成员函数的返回值
|
|||
|
|
- 能取任意类型,包括
|
|||
|
|
- 基本数据类型
|
|||
|
|
- 自定义类型
|
|||
|
|
|
|||
|
|
## 虚函数
|
|||
|
|
|
|||
|
|
### override
|
|||
|
|
|
|||
|
|
声明显式函数覆盖,在编译期间发现未覆盖的错误。
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 数据共享和保护
|
|||
|
|
|
|||
|
|
## 作用域
|
|||
|
|
|
|||
|
|
- 同名隐藏
|
|||
|
|
- 标识符冲突,若作用域嵌套,则识别为内层标识符,外层该标识符不可见
|
|||
|
|
|
|||
|
|
- 作用域分辨符 ::
|
|||
|
|
- 访问被隐藏的标识符
|
|||
|
|
|
|||
|
|
### 块
|
|||
|
|
|
|||
|
|
块中声明的标识符
|
|||
|
|
|
|||
|
|
起于块终于块
|
|||
|
|
|
|||
|
|
生存周期和块一致
|
|||
|
|
|
|||
|
|
块外无法访问
|
|||
|
|
|
|||
|
|
### 类
|
|||
|
|
|
|||
|
|
定义在类中的标识符
|
|||
|
|
|
|||
|
|
public 标识的接口 可以在类外访问
|
|||
|
|
|
|||
|
|
生存周期和类一致
|
|||
|
|
|
|||
|
|
### 文件
|
|||
|
|
|
|||
|
|
全局标识符
|
|||
|
|
|
|||
|
|
若有在文件外访问,需要添加修饰符 extern
|
|||
|
|
|
|||
|
|
生存周期和程序一致
|
|||
|
|
|
|||
|
|
### 命名空间
|
|||
|
|
|
|||
|
|
解决类名函数名冲突
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
namespace ouc{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
using namespace ouc;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
### 限定枚举
|
|||
|
|
|
|||
|
|
限制枚举值的作用域
|
|||
|
|
|
|||
|
|
## 变量生存期
|
|||
|
|
|
|||
|
|
### 静态变量
|
|||
|
|
|
|||
|
|
全局变量、static 变量
|
|||
|
|
|
|||
|
|
- 静态生存期
|
|||
|
|
- 生存期与程序相同
|
|||
|
|
- 静态变量只初始化一次,且作用域内唯一
|
|||
|
|
|
|||
|
|
### 动态变量
|
|||
|
|
|
|||
|
|
块作用域、非static变量
|
|||
|
|
|
|||
|
|
- 动态生存期
|
|||
|
|
- 生存期与作用域一致
|
|||
|
|
|
|||
|
|
## 类的共享 -- 友元
|
|||
|
|
|
|||
|
|
将模块 A 声明为模块 B 的友元
|
|||
|
|
A 成为 B 信任的模块
|
|||
|
|
A 能够引用 B 中被隐藏、封装的信息
|
|||
|
|
|
|||
|
|
### 友元函数
|
|||
|
|
|
|||
|
|
友元函数声明 = friend + 函数声明
|
|||
|
|
|
|||
|
|
### 友元类
|
|||
|
|
|
|||
|
|
友元类声明 = friend + 类声明
|
|||
|
|
|
|||
|
|
## 数据保护
|
|||
|
|
|
|||
|
|
const 修饰符
|
|||
|
|
|
|||
|
|
- 修饰变量
|
|||
|
|
- 保护变量不被修改
|
|||
|
|
|
|||
|
|
- 修饰成员变量
|
|||
|
|
- 只能在构造函数外的初始化列表中赋初值
|
|||
|
|
|
|||
|
|
- 修饰成员函数
|
|||
|
|
- 不更新类对象
|
|||
|
|
- 参与函数重载
|
|||
|
|
|
|||
|
|
# 数据结构
|
|||
|
|
|
|||
|
|
## 数组
|
|||
|
|
|
|||
|
|
线性数据结构
|
|||
|
|
|
|||
|
|
数组名是常量指针,内存空间连续
|
|||
|
|
|
|||
|
|
### 静态数组
|
|||
|
|
|
|||
|
|
### 动态数组
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 程序设计
|
|||
|
|
|
|||
|
|
组合和继承能实现设计代码重用
|
|||
|
|
|
|||
|
|
## 输入输出流
|
|||
|
|
|
|||
|
|
常用流
|
|||
|
|
|
|||
|
|
- ostream istream
|
|||
|
|
|
|||
|
|
- ofstream iftream
|
|||
|
|
|
|||
|
|
- ostringstream istringstream
|
|||
|
|
|
|||
|
|
流运算符
|
|||
|
|
|
|||
|
|
- cin >> &a;从流中提取 , >>流提取运算符
|
|||
|
|
|
|||
|
|
- cout<< a;向流中插入,流插入运算符
|
|||
|
|
|
|||
|
|
cout cin 常用函数
|
|||
|
|
|
|||
|
|
默认右对齐
|
|||
|
|
|
|||
|
|
- 设置宽度 setw 、width
|
|||
|
|
- 设置填充字符 setfill
|
|||
|
|
- 设置进制 dec、oct 、hex
|
|||
|
|
- 设置对齐方式 setiosflags(ios_base::left)
|
|||
|
|
- 设置有效位数 setprecision
|
|||
|
|
|
|||
|
|
## 异常
|
|||
|
|
|
|||
|
|
特殊的返回值 和捕获流程
|
|||
|
|
|
|||
|
|
异常对象为自定义任意类型 的对象
|
|||
|
|
|
|||
|
|
throw 异常对象;
|
|||
|
|
|
|||
|
|
try{
|
|||
|
|
|
|||
|
|
}catch(异常对象){
|
|||
|
|
|
|||
|
|
捕获异常
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|