上了一周多pl/sql和proc...感觉proc这东西好鸡肋..像个半成品..就不总结了
c++部分
结构体是特殊的类,使用可以省略struct关键字
struct默认是public,class默认是private
所以很多stl类直接写为struct
运算符别名
&& and
|| or
....
还有 {}=<% %>之类的
重载
同一作用域,函数名相同,参数列表不同
和返回值无关
nm命令查看.o文件 可以看到真实的函数名
加入extern 'C' 让编译器不改名
函数的参数缺省值在声明中加入,实现中不加入,缺省值的右边不能有非缺省参数
inline是在运行期间二进制代码替换
类成员函数默认inline
free之后设置null
delete 用于释放单个
delete[] 用于释放数组 ,stl里面有个什么是数组实现得用delete[],但是忘了
int* a[5]指针数组
int(*a)[5] 首先*a表示指针, 表示指向长度为五的数组的指针
引用
起别名, 必须定义时初始化
不能为null
不能改变目标
引用本质还是指针
double& m=d;=>double* const pm=&d;
不能使用双重引用
int*& pa=pa; 指针饮用
new
new(p) int(3);
定向分配 , p是指针
int *p[2]=new int[2]{2,3}; c++11才开始支持用指针声明数组同时初始化;
类
没什么特别..
初始化列表按照声明顺序初始化
空类的sizeof为1
(静态成员变量)和成员函数不属于在对象空间,在代码区
静态成员变量必须在类外初始化
静态成员函数只能调用静态成员变量
stl中很多函数有const版本和应用版本
const对象只能调用const 版本,一般对象都可以调用,优先使用不转换类型的版本
成员指针
int classname::*p_name;
p_name=&classname::m_n;
使用
c(.*)/(->*)p_name;
运算符重载
编译器为区分前++和后++,会向后++传一个int(0)来区分
友元,有所有权限,友元类可以访问定义类,反之不行
类成员也有对齐和补齐
继承 子类如果出现了父类的标识符,就会隐藏父类的标识符部分.
多态
针对虚函数用的功能
运行时会根据实际类型调用,覆盖操作
如果不是虚函数,按照类的类型调用,而不是实际类型调用
虚继承和虚函数 没关系
虚继承是在一个对象的整个继承中只有一个基类
虚继承产生一个虚表,在类中占用一个指针空间
左边包含距离基类距离,右边是虚函数表,根据实际类不同,各个子集类的虚函数表会拷贝父类,然后覆盖成自己的
虚继承中父类的虚表会被丢弃
访控属性针对子类的下一级使用,对子类本身不起作用
<<stl源码剖析>>部分
空间配置器
第一级空间配置器, 使用malloc/free,当申请内存大于128bytes时使用;
第二级空间配置器
使用一个指针维护一个表,表中没有被使用的空间叫内存池
f[16]分别指向8,16,24,32..,128的区域.f[3]指向40bytes区块这样的一个表
总共加起来4096,一页
过程:
slt原玛剖析 p68
chunk_alloc(32,20);
malloc配置20*2个32bytes内存块 ,第一个交出,另外19个交给f[3]维护,会多分配一倍用于备用,剩余20个交给内存池
然后
chunk_alloc(64,20);
f[7]是空的
内存池还剩(32*20)/64=10个区块,就把这10个区块返回,第一个交给客户端,剩余9个交给f[7],内存池空了
然后
chunk_alloc(96,20)这是 96bytes对应的f[11]为空,先查看内存池,这是为空,继续用malloc配置40+n个96bytes区块,一个交出,19个交给f[11]维护,剩余的给内存池
n的大小由实现决定
如果最后malloc失败,找不到多余空间,抛出bad_alloc异常
traits技法
使用模板的特化或偏特化,使一般指针,常指针,迭代器和自定义迭代器拥有相同的几个型别
p91
value_type;
difference_type;
pointer;
reference;
iterator_category;
迭代器型别:iterator_category;
struct input_iterator_tag{};
output iterator tag{};
forward_iterator_tag:public input_iterator_tag{};
bidirectional_iterator_tag:public forward_iterator_tag{};
random_access_iterator_tag:public bidirectional_iterator_tag{};
c++标准库那本书也有这个,
_advance(i,n,input_iterator_tag());
算法使用型别当参数用来选择特化的算法函数
不同型别的实现不同
__ture_type和__false_type两个空类 用来检测特定类型是否支持一些迭代器的操作(构造,拷贝,赋值....) ,本可以用bool值做的一些事情,直接用模板来做了..境界..
vector 的内部型别实现
p115
typedef T value_type;
typedef value_type* pointer;
typedef value_type* iterator;
typedef value_type& reference;
typedef size_t size_type;
iterator start;//begin()返回
iterator finish;//end()返回
iterator end_of_storage;
在这里 iterator只是一个型别,但有些情况下iterator是一个内部类,
得出结论:iterator只是一个标准的接口,根据实现不同,表现相同行为,但本质不一定一样
完全没有任何废代码.太强大的范型的思维...膜拜
clear()是调用了erase(begin(),end());