# 绪论

## 程序语言

- 机器语言
  - 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(异常对象){

​	捕获异常

}



