C++学习

学习日记

Posted by BY Bigboss on April 2, 2022

C++基础01

1.#include<iostream>
	1.1 using namespace std;
	1.2 cout<<"Hello world"<<endl;
	1.3 system("pause")
	1.4 return 0;
2.::双冒号作用域运算符
	2.1 全局作用域 直接加::
3.namespace命名空间
	3.1 用途 解决名称冲突问题
	3.2 必须在全局作用域下声明
	3.3 命名空间下可以放入函数,变量,结构体,类
	3.4 命名空间可以嵌套命名空间
	3.5 命名空间是开放的,可以随时加入新的成员
	3.6 匿名命名空间static
4.using声明和using编译指令
	4.1using LOL::sunwukongID;
	4.2如果局部范围内还有sunwukongID,会出现二义性问题,要避免使用
	4.3编译指令using namespace LOL
	4.4如果局部范围内还有sunwukongID,使用局部的ID
	4.5如果打开多个房间,那么也要注意二义性问题
5.C++对c语言的增强
	5.1.全局变量检测增强
	5.2.函数检测增强(参数类型增强,返回值检测增强,函数调用参数检测增强)
	5.3.类型转换增强(malloc返回void*,c中可以不用强转,c++必须强转)
	5.4.struct增强(c++中可以加函数,使用的时候不需要加struct关键字)
	5.5.bool类型增强(c中没有,c++有true,false,sizeof为1)
	5.6.三目运算符增强(c中返回的是值,c++中返回的是变量)
	5.7.const增强(c语言是伪常量可以通过指针修改,c++中定义的是真正的常量,c语言中的const默认的是外部链接,c++中默认的是内部链接)(c++中分配内存的就可以通过指针进行修改1.const分配内存,取地址会分配临时内存2.extern编译器也会给const分配内存3.用普通变量初始化const的变量4.自定义数据类型const也会分配内存)
6.引用基本语法
	6.1
	用途起别名
	Type&别名=原名
	引用必须初始化
	一旦引用后,不能修改
	对数组建立引用
	6.2参数传递的三种传递方式
	值传递,地址传递,引用传递
	6.3注意事项,不能返回局部变量的引用
	6.4如果函数返回值是引用,那么函数的调用可以作为左值
	6.5引用的本质,就是一个指针常量
7.指针的引用
	7.1用一级的指针引用 可以代替二级的指针
8.常量引用
	8.1使用场景 修饰形参为只读
8.2 const int&a =10会分配内存

C++基础02

1.设计类 抽象类
	1.1 class类名{
	1.2 public 公共权限
	1.3 设置 成员属性
	1.4设置 成员函数
	1.5 }
	1.6 使用类 创建对象 实例化对象
	1.7 类名 对象名
	1.8 通过对象 来设置属性 调用成员函数
	1.9 类和对象关系?
		1.9.1 类是对对象的抽象
		1.9.2 对象是对类的实例
2 内联函数 解决宏缺陷问题
	2.1 给编译器一个建议,加上关键字,编译器不一定按照内联处理
	2.2 不加关键字,也许编译器还偷摸的给你加inline
	2.3 成员函数 默认加上关键字
3 函数默认参数
	3.1 函数可以有默认值
	3.2 如果有一个位置有了默认值,那么从这个位置开始,从左到右都必须有默认值
	3.3 函数声明和实现,可能有一个默认值(不能两个都有)
4 函数占位参数
	4.1 void func(int)占位参数 调用时候必须要提供这个参数
	4.2 占位参数也可以有默认值
	4.3 c语言中没有默认参数和占位参数
5 函数重载的基本语法
	5.1 函数名称相同,又在同一个作用域下
	5.2 函数参数个数不同,类型不同,顺序不同都可以满足重载条件
	5.3 函数的返回值可以作为函数重载条件吗?不可以
	5.4 当函数重载碰到了函数默认参数,要避免二义性
6 extern c 浅析
	6.1 解决了c++文件中调用c语言的代码
	6.2 ifdef __cplusplus extern "C"{
	6.3 }
7 C++语言的封装
	7.1 讲属性和行为作为一个整体,来表示生活中具体的事物
	7.2 有访问权限
	7.3 class和struct 唯一区别 默认权限不同 class默认是private struct默认是pulic
	7.4 public是类内类外都可以访问到
	7.5 protected类内可以,类外不可以
	7.6 private 类内可以,类外不可以
8 建议将所有的成员属性设置为私有
	8.1 自己提供公共的对外接口来进行set或者get方法访问

C++基础03

1 立方体案例
2 点和圆关系案例
	2.1 圆内的属性里有个其他的自定义数据类型 Point
	2.2 三种关系判断
	2.3 分文件编写
		2.3.1 .h中写类的成员函数声明
		2.3.2 .cpp中写成员函数实现
3 对象的初始化和清理
	3.1 构造函数
		3.1.1 没有返回值 没有void 类名相同,可以发生重载,可以有参数
	3.2 析构函数
		3.2.1 没有返回值 没有void,函数名称~加类名,不可以发生重载,没有参数
	3.3 系统会默认调用构造函数和析构函数,而且只会调用一次
	3.4 如果程序员没有提供构造和析构,系统会默认提供,空实现
4 构造函数的分类及调用
	4.1 按照参数分类
		4.1.1 无参构造(默认构造) 有参构造
	4.2 按照类型分类
		4.2.1 普通构造函数 拷贝构造函数
	4.3 无参构造写法和调用
		4.3.1 persion p1;注意不能写persion p1(),因为编译器认为这个是函数声明
	4.4 有参构造写法和调用
		4.4.1 persion p2(10)或者persion p1=persion(p2)
		4.4.2 persion(10)匿名对象,执行当前行后就会释放这个对象
	4.5 拷贝构造函数
		4.5.1 persion(const persion &p)
		4.5.2 persion p1(p2)或者persion p1=persion(p2)
		4.5.3 不能用拷贝构造函数初始化匿名对象
			4.5.3.1 如果写成persion(p1)这种写法等价于persion p1
			4.5.3.2写到右值可以做拷贝构造参数
	4.6 persion p=100 隐式类型转换 相当于调用persion p=persion(100)
5 构造函数的调用规则
	5.1 用已经创建好的对象来初始化新的对象
	5.2 以值传递的方式给函数参数传值
	5.3 以值方式返回局部对象
	5.4 release默认下会做优化
6 构造函数的默认规则
	6.1 如果提供了有参的构造,那么系统就不会提供默认的构造了,但是会提供拷贝构造
	6.2 如果提供了拷贝构造函数,那么系统就不会提供其他的构造函数了
7 深拷贝与浅拷贝
	7.1 系统默认提供的拷贝构造,会进行简单的值拷贝
	7.2 如果属性里有指向堆栈空间的数据,那么简单的浅拷贝会导致重复释放内存的异常
	7.3 解决上述问题,需要我们自己提供拷贝构造函数,进行浅拷贝
8 初始化列表
	8.1 在构造函数后面+:属性(值,参数), 属性(值,参数)
9 类对象作为成员的案例
	9.1 当类对象作为类的成员的时候,构造顺序是先构造类对象的构造,然后构造自己
	9.2 析构顺序与构造相反
10 explicit关键字
	10.1 防止构造函数中的隐式关键字转换
11 new运算符和delete运算符
	11.1 new会创建一个该类型的指针
	11.2 默认调用构造函数,默认开辟空间,返回类型指针,不需要强制转换
	11.3 delete来释放
	11.4 new对象用void*来接受,释放不了对象
	11.5 new出来的数组,如何释放 delete[]
	11.6 new出来的数组,肯定会调用默认构造

C++基础04

	1. 静态成员变量和静态成员函数
		a. 静态成员变量
			i. 编译阶段分配内存
			ii. 所有对象共享数据
			iii. 通过对象访问,通过类名访问
			iv. 有权限控制
			v. 类内声明 类外初始化
		b. 静态成员函数
			i. 可以访问静态的成员变量,不可以访问普通成员变量
			ii. 普通的成员函数都可以访问
			iii. 静态成员函数也有权限
			iv. 可以通过对象访问,也可以通过类名进行访问
	2. 单例模式案例-主席
		a. 目的 为了让类中只有一个实例,实例也不需要自己释放掉
		b. 将默认构造和拷贝构造私有化
		c. 内部维护一个对象的指针
		d. 私有化唯一指针
		e. 对外提供getinstance(自己定义的函数)方法来访问这个指针
		f. 保证类中只能实例化唯一一个对象
	3. 单例模式案例-打印机
		a. 类似主席案例
		b. 提供打印功能
	4. c++对象模型初探
		a. 成员函数和成员属性是分开存储的
		b. 空类的大小
		c. 只有非静态成员才属于对象身上
	5. this指针使用
		a. 指针永远指向当前对象
		b. 解决命名冲突
		c. “this”指向对象本体
		d. 非静态的成员函数才有this指针
	6. 空指针访问成员函数
		a. 如果成员函数没有用到this,那么空指针可以直接访问
		b. 如果成员函数没有用到this指针,就要注意,可以加if判断,如果this为NULL,就return掉
	7. 常函数 常对象
		a. 常函数 void func() const {}常函数
		b. 常函数 修饰是this指针 const Type *const this
		c. 常函数不能修改this指针执行的值
		d. 常对象 在对象前假如const 修饰const person p1
		e. 常对象不可以调用普通的成员函数,常对象是可以调用常函数
	8. 友元
		a. 全局函数是友元函数
			i. 全局函数写到类中做声明 并且最前面写friend作为关键字
		b. 让整个类做友元函数
			i. friend class类名
		c. 友元函数不能继承
		d. 友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友
		e. 友元关系不具有传递性,类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友
		f. 成员函数做友元函数
			i. friend void goodGay::visit()

C++基础05

	1. 加号运算符重载
		a. 如果想让自定义数据类型 进行+运算,那么就需要重载+运算符
		b. 在成员函数或者全局函数里重写一个+运算符的函数
		c. 函数名operator+()
		d. 运算符重载也可以提供多个版本
	2. 左移运算符重载
		a. 不要随意乱用符号运算符
		b. 内置数据类型的运算符不可以重载
		c. cout<<直接对Persion自定义数据类型 进行输出
		d. 写到全局函数中 ostream& operator<<(ostream &cout, Persion &p1){}
		e. 如果重载时候想访问p1的私有成员,那么全局函数要做Persion的友元函数
	3. 前置后置++运算符重载
		a. 自己实现一个int类型Myinteger
		b. 内部维护int数据
		c. MyInteger myInt
		d. myint++后置 ++myint前置
		e. 重载++运算符 operator++()前置 operator++(int)后置
		f. 前置理念 先++后返回自身 后置 先保存住原有的值,内部数据++,返回临时数据
	4. 智能指针实现
		a. Persion类有showAge成员函数
		b. 如果new出来的persion对象,就要让程序员自觉的去释放delete
		c. 有了智能指针,让智能指针托管这个Persion对象,对象的释放就不用操心了,让智能指针管理
		d. 为了让智能指针和普通的指针一样,就应该重载<<运算符和*运算符
	5. 赋值运算符重载
		a. 系统默认给类提供 赋值运算符写法 是简单值拷贝
		b. 导致如果类中有指向堆区的指针,就可以出现深浅拷贝的问题
		c. 所以要重载=运算符
		d. 如果想链式编程return this
	6. []运算符重载
		a. 返回数组索引的引用
		b. int &operator[](int index)
		c. return this->pAdress[index]

C++基础06

	1. 关系运算符重载
		a. 自定义数据类型 不会内部做比较 == != 
		b. 所以要重载 == !=
	2. 函数调用运算符重载
		a. ()仿函数 对象() 看似像函数调用
		b. Myadd()匿名对象
	3. 不要重载 &&和||
		a. 本身有短路特性我们无法去实现这种特性
		b. 所以不要重载
	4. 强化字符串封装
		a. cout输出自定义的字符串
		b. cin让用户输入自定义的字符串
		c. 重载=运算符
		d. 重载+运算符
		e. 重载[]运算符
		f. 重载==运算符
	5. 继承的引出
		a. 网页有很多公共的部分
		b. 导致实现的时候有很多重复的代码
		c. 引出继承,基类(父类)公共网页
		d. 具体子类 实现不同的内容
		e. 语法 class 子类 : 继承方式 父类
	6. 继承方式
		a. 不管是公有继承 保护 还是私有 基类中的私有属性,都不可以继承下去
		b. 公有继承(public),父类中的protected 在子类中是protected
			i. 父类中的public在子类中是public
		c. 保护继承(protected)
			i. 父类中的protected在子类中是protected
			ii. 父类中的public在子类中是protected
		d. 私有继承(private)
			i. 父类中的protected在子类中是private
			ii. 父类中的public在子类中是private
	7. 继承中的对象模型
		a. 子类会继承父类中的所有内容,包括了私有属性
		b. 只是我们访问不到,编译器给隐藏了 
		c. cd reportSingleClassLayout类名 文件名
	8. 继承中的构造和析构顺序
		a. 子类创建对象的时候,先调用父类的构造,然后调用自身构造
		b. 析构顺序与构造顺序相反
		c. 子类是不会继承父类的构造函数和析构函数,operator=也不会
		d. 补充内容:如果父类中没有合适默认构造,那么子类可以利用初始化列表的方式显示的调用父类的其他构造
	9. 继承中的同名处理
		a. 成员属性 直接调用先调用子类 需要作用域
		b. 成员函数 直接调用先调用子类,父类的所有版本都会被隐藏,除非显示用作用域运算符去调用
	10. 继承中静态成员的处理
		a. 类似非静态成员函数处理
		b. 如果想访问父类中的成员,加作用域即可
	11. 多继承的概念以及问题
		a. class A:public B1,public B2,…
		b. 引发二义性问题
		c. 想解决二义性问题,就需要通过作用域解决
	12. 菱形继承问题及解决
		a. 解决菱形问题利用虚基类
		b. 虚基类内部结构
			i. vbptr虚基类指针
			ii. 指向一张虚基类表
			iii. 通过表找到偏移量
      			iv. 找到公有数据

C++基础07

多态:父类的引用,指针指向子类对象
	1.   静态联编和动态联编
		a. 多态分类
			i. 静态多态 函数重载
			ii. 动态多态 虚函数 继承关系
		b. 静态联编
			i. 地址早绑定 编译阶段绑定好地址
		c. 动态联编
			i. 地址晚绑定,运行时候绑定好地址
		d. 多态
			i. 父类的引用或指针指向子类对象
	2. 多态的原理解析
		a. 当父类中有了虚函数后,内部结构就发生了改变
		b. 内部多了一个vfptr
			i. virtal function pointer 虚函数表指针
			ii. 指向vftable虚函数表
		c. 父类结构 vfptr &animal::speak
		d. 子类中进行继承,会继承vfptr vftable
		e. 构造函数中会将虚函数表指针指向自己的虚函数表
		f. 如果发生了重写,会替换掉虚函数中原有的speak,改为&cat::speak
		g. 深入剖析,内部到底如何调用
		h. ((void(*)())(*(int*)*(int*)animal))()
	3. 多态案例-计算机案例
		a. 早期方法 是不利于拓展
		b. 开发有原则 开闭原则 对拓展开放 对修改关闭
		c. 利用多态实现-利于后期拓展,结构性非常好,可读性高,频率稍微低,发生多态内部结构复杂
	4. 抽象类和纯虚数类
		a. 纯虚函数写法 virtual void func()=0
		b. 抽象类型
		c. 抽象类 不可以实例化对象
		d. 如果类继承了抽象类,必须重写抽象类中的纯虚函数
	5. 虚析构和纯虚析构
		a. 虚析构
			i. virtual ~类名()=0
			ii. 类内声明 类外实现
			iii. 如果出现了纯虚析构函数,这个类也算抽象类,不可以实例化对象
	6. 向上类型转换和向下类型转换
		a. 基类转派生类
			i. 向下类型转换 不安全的
		b. 派生类转基类
			i. 向上类型转换 安全
		c. 如果发生多态
      			i. 总是安全的

C++基础08

	1. 函数模板基本使用
		a. templa<class/typename T>告诉编译器紧跟的代码里面出现T不要报错
		b. myswap(T &a,&b)类型也许要传入,类型参数化
		c. myswap(a,b)自动类型转换 按照ab的类型来替换T
		d. myswap<int>(a,b)显示指定类型
	2. 函数模板与普通函数的区别与调用规则
		a. 区别 普通函数可以进行隐式类型转换 模板不可以
		b. 调用规则
			i. c++编译器优先考虑普通函数
			ii. 可以通过空模板实参列表的语法限定编译器只能通过模板匹配
			iii. 函数模板可以像普通函数那样被重载
			iv. 如果函数可以产生一个更好的匹配,那么选择模板
		c. 模板的机制
			i. 模板并不是万能的,不能通过所有的数据类型
			ii. 模板不能直接调用,生成后的模板函数才可以调用
			iii. 二次编译,第一次对模板进行编译,第二次对替换T类型后的代码进行编译。
	3. 模板局限性
		a. 模板不能解决所有的类型
		b. 如果出现不能解决的类型,可以通过第三种具体化来解决问题
		c. template<>返回值 函数名<具体类型>参数
	4. 类模板的基本使用
		a. 写法template<T1,T2,…>紧跟着写类
		b. 与函数模板区别,可以有默认类型参数
		c. 函数模型可以进行自动类型推导,而类模板不行
		d. 成员函数一开始不会创建出来,而是在运行时才回去创建
	5. 类模板做函数的参数
		a. 三种方式
			i. 显示指定类型
			ii. 参数模板化
			iii. 整体模板化
		b. 查看类型名称
			i. cout<<typeid(T).name()<<endl;
	6. 当类模板碰到继承
		a. 基类如果是模板类,必须让子类告诉编译器基类中的T到底是什么类型
		b. 如果不告诉,无法分配内存,编译出错
		c. 利用参数列表class Child : public Base<int>
	7. 类模板的类外实现成员函数
		a. template<class T1,class T2>
		b. Persion<T1,T2>::Persion(T1 name,T2 age)
	8. 类模板的分文件编写问题以及解决
		a. .hpp分别写声明和实现
		b. 但是由于类模板的成员函数运行阶段才去创建,导致包含.h头文件,不会创建函数的实现,无法解析外部命令
		c. 解决方案 保护.cpp文件(不推荐)
		d. 不要进行分文件编写,写到同一个文件中,进行声明和实现,后缀改为.hpp
		e. 约定俗成的
	9. 类模板碰到友元函数
		a. 友元函数类内实现
		b. friend void printPersion(Persion<T1,T2>& p)
		c. 友元函数类外实现
		d. friend void printPersion<>(Persion<T1,T2>& p)
    		e. 利用空参数列表告诉编译器是模板函数的声明,让编译器看到Persion类(类)声明,让编译器提前看到printPersion(函数)声明

C++基础09

	1. 类型转换
		a. 静态转换 static_cast
		b. 使用方式 static_cast<目标类型>(原始数据)
		c. 可以进行基础数据类型转换
		d. 父与子类型转换
		e. 没有父子关系的自定义数据类型不可以转换
		f. 动态转换 dynamic_cast
		g. 不可以转换基础数据类型
		h. 父子之间可以转换
			i. 父转子不可以
			ii. 子转父可以
			iii. 发生多态 都可以
		i. 常量转换 const_cast
		j. 不能对非指针或者非引用进行转换
		k. 重新解释转换 reinterpret_cast
			i. 最不安全,最鸡肋
	2.   异常
		a. try 试图执行try{}中的内容
		b. 在可能出现异常的地方抛出异常 throw
		c. try下面catch捕获异常
		d. catch{捕获类型}   …代表所有其他类型
		e. 如果不想处理异常,继续向上抛出throw
		f. 如果没有处理任何异常的地方,那么成员调用terminate函数,处理中断
		g. 自定义异常类,可以抛出自定义的对象,捕获自定义的对象
	3. 栈解旋
		a. 从try开始到throw抛出异常之前 所有栈上的对象,都会被释放,这个过程称为栈解旋
		b. 栈上对象构造顺序与析构顺序相反
	4. 异常的接口声明
		a. 如果想抛出特定的类型异常,可以利用异常的接口声明
		b. void func()throw(int)只能抛出int异常
		c. throw()不抛出任何类型
	5. 异常变量的生命周期
		a. 如果MyException e,会多开销一份数据,调用拷贝构造
		b. 如果MyException *e,不new提前释放对象new自己管理delete
		c. 推荐MyException &e容易些,而且就一份数据
	6. 异常的多态使用
		a. 利用多态来实现printError同一个接口调用
		b. 抛出不同的对象,提示不同的错误
	7. 使用系统标准异常
		a. #include<stdexcept>
		b. throw out_of_range("aaa")…
		c. catch(out_of_range &e) c e.what()
	8. 编写自己的异常
		a. 自己的异常类 需要继承与exception
		b. 重写 虚析构what()
		c. 内部维护以错误信息 字符串
		d. 构造时传入 错误信息字符串,what返回字符串
		e. string转char* .c_str();
	9. 标准输入流
		a. cin.get 缓冲区中读取一个字符
		b. cin.get(两个参数)不读换行符
		c. cin.getline() 读取换行 并且扔掉
		d. cin.ignore忽略(N)N代表字符数
		e. cin.peek偷窥 偷看一个字符然后放回去
		f. cin.putback放回 把字符放回缓冲区
	10. 输入流案例
		a. 判断用户输入的是字符串还是数字,利用偷窥或者放回
		b. 让用户输入指定范围内的数字,如果不正确,重新输入
			i. cin.fail()看标志位0正常1不正常
			ii. cin.clear()重置标志位
			iii. cin.sync()清空缓存区
	11. 标准输出流
		a. 流对象的成员函数
			i. int number = 99;
			ii. cout.width(20);
			iii. cout.fill('*');
			iv. cout.setf(ios::left);//设置格式 输入内容对其
			v. cout.unsetf(ios::dec;)//卸载十进制
			vi. cout.setf(ios::hex);//安装16进制
			vii. cout.setf(ios::showbase);//强制输出整数基数 0 0x
			viii. cout.unsetf(ios::hex);
			ix. cout.setf(ios::oct);
			x. cout<<number<<endl;
		b. 控制符
			i. int number = 99;
			ii. cout<<setw(20)
			iii. <<setfill('~')
			iv. <<setiosflags(ios::showbase)//基数
			v. <<setiosflags(ios::left)//左对齐
			vi. <<hex//十六进制
			vii. <<number
			viii. <<endl;
	12. 文件操作
		a. 写文件
			i. ofstream
			ii. open指定打开方式
			iii. isopen判断是否打开成功
			iv. ofs<<"数据"
			v. ofs.close
		b. 读文件
			i. ifstream ifs
			ii. 指定打开方式 ios::in
			iii. isopen判断是否打开成功
      			iv. 三种方式读取数据

C++ STL10

STL广义上分为:容器(container)算法(algorithm)迭代器(iterator)
六大组件:容器,算法,迭代器,仿函数,适配器(配接器),空间配置器
	1. 三大组件
		a. 容器vector
		b. 算法for_each 头文件algorithm
		c. 迭代器 iterator 每个容器有专属迭代器
			i. victor<int>v
			ii. vector<int>::iterator it=…
			iii. v.begin()指向第一个数据
			iv. v.end()指向最后一个数据的下一个数据
	2. string容器
		a. 构造 赋值 assign
		b. 对字符存取 [] at 区别
			i. []访问越界 直接挂
			ii. at 抛出 异常 out_of_range
		c. substr 配合find查找 邮件用户名
		d. char* string互转
			i. char* 隐式转换 string反而不可以
		e. 转大写toupper
		f. find 如果找不到 返回-1
			i. 找到返回第一次出现的位置
	3. vector容器
		a. 构造,赋值
		b. 大小 size 重置大小 resize 容量 capacity
		c. 是否为空 empty 交换 swap
		d. 巧用swap收缩空间
		e. eserve预留空间
		f. insert插入(迭代器)erase删除(迭代器)clear()清除容器
		g. pop_back 尾删 front 第一个数据 back 最后一个数据
		h. 逆序遍历 reverse_iterator rbegin rend
		i. 如何区分迭代器是否支持随机访问(写一下不报错就是支持)
	4. deque容器
		a. 双端数组 没有容量
		b. API     赋值,构造,大小,交换,插入,删除
		c. 头部删除 头部插入
			i. pop_front
			ii. pish_front
		d. 3中迭代值 iterator普通 reverse_iterator 逆序迭代器 const_iterator 只读迭代器
		e. 排序sort引用头文件algorthim
			i. sort(d.begin(),d.end());

C++ STL11

	1. stack栈容器
		a. 先进后出
		b. 栈顶 top
		c. 压栈 push
		d. 弹出栈顶 pop
		e. 大小 size
		f. 是否 empty
	2. queue队列容器
		a. 先进先出
		b. 队尾back 队头front
		c. 入队push
		d. 弹出队头pop
		e. 大小size
		f. 为空empty
	3. list容器
		a. 赋值,构造,大小,为空,删除,添加
		b. 删除remove(10) 删除容器中所有与10有关的元素
		c. 双向循环链表
		d. 迭代器是不支持随机访问的
		e. 反转排序
			i. reverse反转
			ii. 排序 成员函数 sort
			iii. 默认排序 从小到大
			iv. 自定义数据类型,必须制定排序规则
			v. 高级排序 指定排序规则
		f. remove删除list容器中自定义数据类型
	4. set容器
		a. 关联式容器
		b. 插入数据自动排序
		c. insert 插入值
		d. erase 参数可以传值或者迭代器
		e. find()返回值迭代器找不到返回的end()
		f. count计数 对于set而言 结果就是0或1
		g. lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器 
		h. upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
		i. equal_range(key_Elem);//返回容器中key与keyElem相等的上下限的两个迭代器
		j. 对组 pair
			i. 第一个值first
			ii. 第二个值second
			iii. 默认括号
			iv. make_pair()
		k. set插入返回值是对组 < 迭代器,是否成功标示
		l. 指定set排序规则,利用仿函数
		m. set插入自定义数据类型
	5. map容器
		a. 每个元素 都是一个pair
		b. 对于map而言key是不可以重复
		c. multimap可以
		d. 4种插入方式
		e. count统计map0或1 multimap可能大于1
		f. 排列规则自己定
使用场景分析:
vector的使用场景:
	比如软件历史操作记录的存储,我们经常要查看历史记录,比如上一次的记录。上上次的记 录,但却不会去删除记录,因为记录是事实的描述。
deque的使用场景:
	比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除,尾端的快速添  加,如果采用vector,则头端移除时,会移动大量的数据,速度慢。
vector与deque的比较:
	1:vector.at()比deque.at()效率高,比如vector.at(0)是固定的,deque的开始位置却是不固定的。
	2:如果有大量释放操作的话,vector花的时间更少,这跟两者的内部实现有关。
	3:deque支持头部的快速插入和快速移除,这是deque的优点。
list的使用场景:
	比如公交车乘客的存储,随时有可能有乘客下车,支持频繁的不确定位置元素的移除插入。
set的使用场景:
	比如对手机游戏的个人得分记录的存储,存储要求从高分到低分的顺序排列。
map的使用场景:
比如按ID号存储十万个用户,想要快速通过ID查找对应的用户,二叉树的查找效率,这时就体现出来了。如果是vector容器,最坏的情况下可能要遍历完整个容器才能找到用户。

C++ STL12

	1. 函数对象(仿函数)
		a. 重载()所以函数的对象 使用()像函数调用
		b. 是类而不是普通的函数
		c. 内部记录状态
		d. 作为类型,与模板进行配合
	2. 渭词
		a. 普通函数或者仿函数返回值bool类型
		b. 一元 一个参数 二元 两个参数
		c. 一元 查找 大于20的数字 find_if返回迭代器
		d. 二元排序
	3. 内建函数对象
		a. 取反
		b. 加法
		c. 大于 greater<int>()
	4. 适配器
		a. 函数适配器
		b. 0~9加起始值 进行输出 用户提供起始值
		c. bind2nd 绑定
		d. 继承 binary_function<参数类型1,参数类型2,返回值类型>
		e. const 修饰operator()
		f. 取反适配器
			i. not1 一元 找出小于5
			ii. not2 二元 排序 not2(less<int>())从大到小 相当于 greater<int>()
		g. 普通函数指针适配
			i. ptr_fun
		h. 成员函数适配
			i. 如果容器存放的是对象指针,那么用mem_fun
			ii. 如果容器中存放的是对象实体,那么用mem_fun_ref
	5. 常用遍历算法
		a. for_each 可有返回值
		b. 可以绑定参数进行输出
		c. transform 将容器中的数值进行搬运到另一个容器中
		d. 注意:目标容器需要开辟空间
	6. 常用查找算法
		a. find 按值查找Person
		b. find_if 按条件查找Person
		c. adjacent_find 算法 查找相邻重复元素 返回第一个重复元素的迭代器位置
		d. binary_search 算法 二分查找法 必须容器是有序序列
		e. count 和 count_if
	7. 常用排序算法
		a. merge算法 容器元素合并,并存储到另一容器中,两容器要有序,并且顺序一致
		b. sort排序
		c. random_shuffle 洗牌 自己提供随机种子
		d. reverse 反转
	8. 常用的拷贝和替换算法
		a. copy复制
		b. replace replace_if 替换
		c. swap交换
	9. 常用函数生成算法
		a. 头文件numeric
		b. accumulate累加
		c. fill 填充
	10. 常用集合算法
		a. 交集 set_intersection
		b. 并集 set_union
		c. 差集 set_difference