07.C++11新特性
C++11新特性 auto decltype :求表达式的类型 智能指针 #include <memory> shared_ptr 可以托管一个new运算符返回的指针 shared_ptr<T> ptr(new T) 此后ptr就可以像T*类型的指针一样来使用, 即*ptr就是用new动态分配的那个对象, 且不必操心释放内存的事 多个shared_ptr对象可以同时托管一个指针, 系统会维护一个托管计数. 当无shared_ptr托管该指针时, delete该指针 shared_ptr对象不能托管指向动态分配的数组的指针, 否则程序运行会出错 右值引用和move语义 右值引用 123class A{ }A& r = A(); // errorA&& r = A(); //...
06.文件操作与模板
文件操作 使用/创建文件的基本流程 打开文件 -> 读写文件 -> 关闭文件 函数模板 1234567891011template<class 类型参数1, class 类型参数2, ...>返回值类型 模板名 (形参表){ 函数体}template <class T>void Swap(T& x, T& y) { T tmp = x; x = y; y = tmp;} 编译器根据类型参数自动生成相应函数 函数模板可以重载 C++编译器遵循以下优先顺序 先找参数完全匹配的普通函数(非由模板实例化而得的函数) 再找参数完全匹配的模板函数 再找实参经过自动类型转换后能够匹配的普通函数 上面的都找不到, 则报错 类模板 1234template <类型参数表>class 类模板名 { ...
05.多态与虚函数
多态和虚函数的基本概念 虚函数 virtual 只用在类定义里的函数声明中, 写函数体时不用 构造函数和静态成员函数不能是虚函数 多态 派生类指针可以赋给基类指针 通过基类指针调用基类和派生类中的同名虚函数时 若该指针指向一个基类的对象, 那么被调用的是基类的虚函数 若该指针指向一个派生类的对象, 那么被调用的是派生类的虚函数 在非构造函数和非析构函数中调用虚函数, 是多态 多态实现原理 编译时不能确定, 运行时才能确定 动态联编 多态会有空间和时间上的额外开销 虚析构函数 在删除一个指向派生类的基类指针时, 只会调用基类的析构函数, 这会导致内存泄漏 解决方法 把基类的析构函数声明为virtual 派生类的析构函数virtual可以不进行声明 通过基类的指针删除派生类对象时 首先调用派生类的析构函数 然后调用基类的析构函数 类如果定义了虚函数, 则最好将析构函数也定义成虚函数 纯虚函数和抽象类 纯虚函数: 没有函数体的虚函数 virtual void print() = 0; 抽象类:...
04.继承与派生
继承与派生 123class 派生类名: public 基类名 { ...}; 派生类对象的内存空间 派生类对象的体积等于基类对象的体积, 再加上派生类对象自己的成员变量的体积. 在派生类对象中, 包含着基类对象, 而且基类对象的存储位置位于派生类对象新增的成员变量之前 派生类中和基类同名同参数表的方法 – 覆盖 (不是重载) 复合关系和继承关系 复合关系 类C中 “有” 成员变量k, k是类D的对象, 则C和D是复合关系 一般逻辑上要求: D对象是C对象的固有属性或组成部分 不能循环定义(我中有你, 你中有我) 基类/派生类同名成员和protected访问范围说明符 基类的 private成员 可被下列函数访问 基类的成员函数 基类的友元函数 基类的 public成员 可被下列函数访问 基类的成员函数 基类的友元函数 派生类的成员函数 派生类的友元函数 其他函数 基类的 protected成员 可被下列函数访问 基类的成员函数 基类的友元函数 派生类的成员函数可以访问当前对象的基类的保护成员...
03.运算符重载
运算符重载的基本概念 对抽象数据类型也能够直接使用C++提供的运算符 123返回值类型 operator 运算符(形参表) { ...} 在程序编译时 把 含运算符的表达式 -> 对 运算符函数 的调用 把 运算符的操作数 -> 运算符函数的参数 运算符被多次重载时, 根据 实参的类型 决定调用哪个运算符函数 重载为普通函数时, 参数个数为运算符目数 重载为成员函数时, 参数个数为运算符目数减一(第二个参数) 不允许定义新的运算符 不是所有运算符都能被重载 () [] -> = 重载时必须声明为类的成员函数 赋值运算符的重载 赋值运算符 “=” 只能重载为 成员函数 浅复制/浅拷贝 执行逐个字节的复制(指针)工作 深复制/深拷贝 将一个对象中指针变量指向的内容复制到另一个对象中指针成员对象指向的地方 赋值运算符重载返回类型void不好 如: a = (b =...
02.类和对象
内联成员函数和重载成员函数 内联成员函数 inline + 成员函数 整个函数体出现在类定义内部 重载成员函数 成员函数 – 带缺省参数 避免缺省参数函数和无参函数的二义性 构造函数 一般构造函数 复制构造函数 只有一个参数, 即对同类对象的引用 T :: T(T&)或T :: T(const T&) 若未定义, 编译器生成默认复制构造函数(完成复制功能) 123456class Complex {private: double real, imag;};Complex c1; //调用缺省无参构造函数Complex c2(c1); //调用缺省的复制构造函数, 将c2初始化成和c1一样 什么时候起作用 当用一个对象去初始化同类的另一个对象时 12Complex c2(c1);Complex c2 = c1; //初始化语句, 非赋值语句 如果某函数有一个参数是类A的对象, 那么该函数被调用时, 类A的复制构造函数将被调用 123456void Func(A...
01.从C走进C++
函数指针 定义形式: 类型名 (*指针变量名)(参数类型1, 参数类型2, ...); 使用方法: 函数指针名(实参表); 12345678910111213#include <stdio.h>void PrintMin(int a, int b) { if (a < b) printf("%d", a); else printf("%d", b);}int main() { void (*pf)(int, int); int x = 4, y = 5; pf = PrintMin; pf(x, y);} qsort库函数 void qsort(void *base, int nelem, unsigned int width,int (*pfCompare)(const void *, const void *)); 12345678910111213141516#include...
05.设备管理
I/O控制器 I/O设备和CPU的"中介" 功能 组成 一个I/O控制器可能会对应多个设备 数据寄存器, 控制寄存器, 状态寄存器可能有多个(如: 每个控制/状态寄存器对应一个具体的设备), 且这些寄存器都要有相应的地址, 才能方便CPU操作. 有的计算机会让这些寄存器占用内存地址的一部分, 称为内存映像I/O; 另一些计算机则采用I/O专用地址, 即寄存器独立编址 I/O控制方式 即: 用什么样的方式来控制I/O设备的数据读/写 注意点 完成一次读/写操作的流程 CPU干预的频率 数据传送的单位 数据的流向 主要缺点和主要优点 程序直接控制方式 完成一次读/写操作的流程 轮询 CPU干预的频率 很频繁, I/O操作开始之前, 完成之后需要CPU介入, 并且在等待I/O完成的过程中CPU需要不断地轮询检查 数据传送的单位 每次读/写一个字 数据的流向 读操作(数据输入) : I/O设备 -> CPU -> 内存 写操作(数据输出) : 内存 -> CPU...
04.文件管理
概述 文件的定义 一组有意义的信息的集合 文件的属性 文件名 标识符: 一个系统的各文件标识符唯一 类型: 指明文件的类型 位置: 文件存放的路径(让用户使用), 在外存的地址(让操作系统使用) 大小 创建时间, 上次修改时间, 文件所有者信息 保护信息: 对文件进行保护的访问控制信息 文件的逻辑结构 文件目录结构 文件的基本操作 操作系统向上层提供的基础功能 创建文件 – create系统调用 读文件 – read系统调用 写文件 – write系统调用 删除文件 – delete系统调用 打开文件 – open系统调用 关闭文件 – close系统调用 文件的物理结构 文件存储空间管理 文件的其他操作 操作系统需要提供的其他文件管理功能 文件共享 文件保护 文件的逻辑结构 用户视角 无结构文件 文件内部的数据就是一系列二进制流或字符流组成 又称"流式文件" 如 .txt...
03.内存管理
概述 内存空间的分配与回收 连续分配管理方式 单一连续分配 固定分区分配 动态分区分配 非连续分配管理方式 内存空间的扩充 覆盖技术 交换技术 虚拟存储技术 地址转换 操作系统需要提供地址转换功能, 负责程序的逻辑地址与物理地址的转换 存储保护 设置上下限寄存器 重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器) 覆盖与交换 覆盖技术 必须由程序员声明覆盖结构, 操作系统完成自动覆盖 缺点: 对用户不透明, 增加了用户编程负担 交换技术 内存空间紧张时, 系统将内存中某些进程暂时换出外存, 把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度) 区别 覆盖是在同一个程序或进程中的 交换是在不同进程(或作业)之间的 连续分配管理方式 为用户进程分配的必须是一个连续的内存空间 单一连续分配 固定分区分配 操作系统需要建立一个数据结构——分区说明表, 来实现各个分区的分配与回收 优点: 实现简单, 无外部碎片 缺点: 当用户程序太大时,...