(1)智能指针是行为类似于指针的类对象,可以帮助管理动态内存分配。可避免:
1)有些内存资源已经被释放,但指向它的指针并没有改变指向(成为了野指针),并且后续还在使用;
2)重复释放同一块内存资源;
3)忘记释放内存,造成内存泄露。
当智能指针过期时,其析构函数将自动调用 delete 释放内存。
(2)智能指针的使用
智能指针包含在头文件 中,有三种 shared_ptr、auto_ptr、unique_ptr、weak_ptr。
1)shared_ptr 智能指针 (强引用)
shared_ptr 实现共享式拥有概念,即多个 shared_ptr 智能指针可以共同指向同一块堆内存。该指针在实现上采用的的是引用计数机制,当某一个指针放弃了该内存的使用权,计数减 1,直至为 0 时,内存释放。
参考:http://c.biancheng.net/view/7898.html
2)auto_ptr 智能指针(C++98 的⽅案,C ++ 11 已抛弃)
auto_ptr 采⽤所有权模式,
auto_ptr p1 (new string ("hello"));
auto_ptr p2;
p2 = p1; //auto_ptr 不会报错.
此时不会报错,p2 接管了 p1 的所有权,但是当程序运⾏时访问 p1 将会报错。所以 auto_ptr 的缺点是:存在潜
在的内存崩溃问题!
3)unique_ptr 智能指针(替代 auto_ptr)
unique_ptr 实现独占式拥有或严格拥有概念。保证同一时间内只有一个智能指针可以指向该对象,可避免资源泄露。
例如
unique_ptr p1 (new string ("auto"));
unique_ptr p2;
p2 = p1; //此时会报错!不可剥夺所有权
3)weak_ptr 智能指针(弱引用)
weak_ptr 是为了配合 shared_ptr 而引入的一种智能指针,它不具有普通指针的行为。可以通过 weak_ptr 获取 shared_ptr 的状态信息,例如:有多少指向相同的 shared_ptr 指针、shared_ptr 指针指向的堆内存是否已经被释放等等。
需要注意的是,当 weak_ptr 类型指针的指向和某一 shared_ptr 指针相同时,weak_ptr 指针并不会使所指堆内存的引用计数加 1;同样,当 weak_ptr 指针被释放时,之前所指堆内存的引用计数也不会因此而减 1。也就是说,weak_ptr 类型指针并不会影响所指堆内存空间的引用计数。
示例:
#include
#include
using namespace std;
int main()
{
std::shared_ptr sp1(new int(10));
std::shared_ptr sp2(sp1);
std::weak_ptr wp(sp2); //三者指向同一块内存
cout << wp.use_count() << endl; //输出和 wp 同指向的 shared_ptr 类型指针的数量
sp2.reset(); //释放 sp2
cout << wp.use_count() << endl;
cout << *(wp.lock()) << endl;
//借助 lock() 函数,返回一个和 wp 同指向的 shared_ptr 类型指针,获取其存储的数据
return 0;
}
输出
2
1
10
(1)模板类 vector
迭代器
STL 函数:for_each、sort()等
(2)基于范围的 for 循环(C++11)
double prices[5] = {1.2, 3.4, 4, 3.1, 1,1}
for (auto x: prices)
cout << x << endl;
STL 是一种泛型编程。面向对象编程关注的是数据,而泛型编程关注的是算法,旨在使用同一个函数处理不同类型的容器。他们之间的共同点是抽象和创建可重用代码。
(1)迭代器
遍历数组元素
for (vector::iterator pr=v.begin(); pr!=v.end(); pr++)
cout << *pr <
或者 C++11 方法
for(auto x: v)
cout<< x <
(2)五种迭代器
输入迭代器
输出迭代器
正向迭代器
双向迭代器
随机访问迭代器
(3)容器种类
参考:https://blog.csdn.net/wangxiaolong_china/article/details/8362540
1)顺序容器
vector:最简单的序列类型,使用最多,支持数组表示法和随机访问。在尾部添加和删除元素的时间是固定的,但在头部或中间插入和删除元素的复杂度为线性时间。
deque:双端队列(double-ended queue)。可在队首或队尾添加或删除元素,时间是固定的。
list:双向链表。在链表任意位置插入或删除元素的时间都是固定的(相当于只需要操作指针指向)。不支持数组表示法和随机访问。
vector 强调的是通过随机访问进行快速访问,而 list 强调的是快速插入和删除。
2)关联容器
关联容器将值与键关联在一起,并使用键来查找值。它的优点在于提供了对元素的快速访问。关联元素允许插入新元素,但不能指定元素的位置。
其中,set 和 multiset 比较特殊,只有键没有值,值就是键。类似 list,但不支持随机访问(按索引访问),会默认从小到大自动排序。set 不允许重复元素,multiset 允许重复元素。
map 与 multimap是存储 key-value(键-值-对)类型的容器。map 只允许 key 与 value 一一对应;multimap一个key可对应多个value。
添加元素时,使用 pair 或 make_pair 使 key 和 value 结合成一个元素(类似结构体),然后再插入。
std::pair pair1(1, 1.1);
std::pair pair2 = std::make_pair(1, 1.1);
std::map map1;
map1.insert(pair1); //插入
map1.insert(pair2);
//遍历输出
for(std::map::iterator it=map1.begin(); it!=map1.end(); it++)
{
std::cout << "First Member: " << it->first << std::endl;
std::cout << "Second Member: " << it->second << std::endl;
}
3)容器适配器
queue:限制比 deque 多,不可随机访问队列元素,也不可遍历队列。常用操作:队尾添加、队首删除。(FIFO)
priority_queue:优先队列。操作和普通队列一致,但元素会默认降序排列。
stack:限制比 vector 多,不可随机访问栈元素,也不可遍历栈。常用操作:栈顶添加、栈顶删除。(LIFO)
C++11 提供了函数指针和函数符的替代品 — Lambda表达式。
(1)STL 将算法库分为四类:
非修改式序列操作:如查找、遍历
修改式序列操作
排序和相关操作
通用数字运算
也可以分类为就地算法(在原存储位置进行操作,如 sort ( ) )和复制算法(将结果存放在另一个存储位置,如 copy() )。