1)STL:
STL是编译时进行替换将模板实例化。
template<typename T, typename Y>
T max(T x,Y y){ ............}
int main() {int a=10; short b=20; cout<<max<int,short>(a, b); }
template<typename M,typename N,typename R,typename T>
class Myclass:public M{ N m_var; R fun(int arg){ ......} typedef T* pointer}
可以设置模版的特例,比如对某些类型的这个函数的实现不能这样,就单独特例化出来。
智能指针:栈区的智能指针会在结束时调用析构函数,如template<T>
{
AutoPtr(T *p=NULL):m_p(p){}
~AutoPtr(void) {delete m_p;}
T* m_p;
}
AutoPtr< int > Pa(new int(10))
T& operator* (void) const { return *m_p;}
T* operator->(void)const {return &**this;}
当为浅拷贝时,会double free ,有两种解决方法:
1、拷贝后,将源对象m_p=NULL,
2、 用个计数器,当计数器为0时再析构。
容器:内存都分配在堆上的。
template<T>
class List
包含了很多节点和Node* m_head ,Node* m_tail
template<T>
class Node
包含 Tm_data, Node * m_prev,Node* m_next;
使用如:list<int> li;li.push_back(30);++li.front();
List的迭代器(是被List包含的):
class Iterator{
private: Node*m_head,Node* m_tail,Node* m_node
Iterator &operator++(void) { m_node=m_node->next;return *this}
Iterator operator++(int){Iterator it=*this,++*this,return it}
T& operator->(void) const{return m_ode->m_data}
T* operator->(void) const{return &**this}
}
List中还有Iterator begin(void){return Iterator(m_head,m_tail,m_head)}
end() 返回尾节点的下一个节点。
List< int >::Iterator it =li.begin();it!=li.end();++it;*it*=*it;
容器:
向量(vector) 双端队列(deque) 列表(list)
堆栈(stack) 队列(queue) 优先队列(priority_queue 优先级越高越先出)
映射map 多重映射multimap 集合 set 多重集合multiset
只有向量和双端队列这种内存连续的容器才提供随机迭代器
vector 在堆区分配内存,且是连续的,若一开始存了5个,push_back()后不够,
会重新在堆区找个大的地方,并拷贝再释放原来的,所以每次这种操作后需要重新使得it=li.begin()
优先队列利用了大顶堆,内部结构是vector或deque,map是树形结构,其中的每个节点是
template<typename FIRST,typename SECOND>的键值对,map的键是唯一的,如:
class pair{ FIRST first;SECOND second}
map<string,in>::iterator it =m.begin();it++; it->first;it->second;
set只有键没有值,multimap和multiset允许键重复,多个同键的用链表串在一起。
2)11语法:
auto 类型推导,using 别名=原名,for(auto i:a),函数绑定:有个库提供了这种模板的,类似于
template < typename T>
class function{}
function<int(int)> f1=一个函数地址a或function<int(void)>f1=bind(fun,10)
cout<<f1(10);cout<<f1();
f1存在个函数指针成员变量b,把a赋给了它,其实调用了f1.operator()(10),然后在这个函数里面调用b。
lambda表达式:局部作用域中定义的匿名函数
cout<<[a,b]{return a<b?b:a;}()<<endl;
cout<<[](int x,int y)->int{return x<y?y:x;}(2,3)<<endl;
[&a,&b]引用捕获,[a,b]值捕获,[this]假如这个函数定义在类中的成员函数中,则还需要捕获这个类的this指针;
[=] [&] 代表引用捕获全部和值捕获全部。
int a=c+d; 分配了个只读属性的临时变量存c+d的值,生命周期以分号结束。
int const& s=a+b; 有引用的话 其生命周期会延长。
右值引用 int &&e=a+c; 但++e仍然正确 ,因为右值引用本身是个左值
int(a) 是右值,它是把a转换为int后存在了一个临时空间的。
左值引用只引用左值,右值引用只引用右值。
move语义:把左值变为右值。
string(string &&str):m_str(str.m_str){str.m_str=NULL;}
string(string const& str):m_str(strcpy(new char[strlen(str.m_str)+1],str.m_str)){}
string& opreator=(sting const & str)
{
{string tmp=str;swap(m_str,tmp.s_str);}
return *this;
}
string& opreator=(sting && str)
{
{string tmp=move(str);swap(m_str,tmp.s_str);}
return *this;
}
移动构造:return时把返回值给临时变量(将亡右值),临时变量在main()中再传到相应的变量,这样很麻烦,
不如直接让渡资源。
11语法引入的unordered_map,unordered_map<string,int>用到了散列表,通过哈希函数实现,键冲突的串成链表解决。
c++的STL和11语法特性
于 2021-07-25 16:02:13 首次发布