note/程序开发/编程语言/C++/C++ 基础.md

626 lines
10 KiB
Markdown
Raw Normal View History

2023-07-05 09:34:06 +08:00
# 绪论
## 程序语言
- 机器语言
- 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(异常对象){
捕获异常
}