# 绪论 ## 程序语言 - 机器语言 - 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 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( 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(异常对象){ ​ 捕获异常 }