这篇文章的内容是动态内存。
这一块有点进阶了,是之前很少接触过的部分了。
关注点有这几个:全局对象、局部对象、局部static对象、动态对象。
提炼一下:静态内存、栈内存、*空间(堆)。不同的内存空间有相对应的对象。
一、动态内存与智能指针
都是重点,每一句话都值得去记忆领会。
1.shared_ptr类
1)make_shared函数
举例:
shared_ptr<int> sp = make_shared<int>(7);
cout << *sp << endl;
2)shared_ptr的拷贝与赋值
关于use_count的使用举例
int s = 20;
shared_ptr<int> p1 = make_shared<int>(s);//
auto p= make_shared<int>(7);
cout << p.use_count() << endl;//
p = p1;
cout << p.use_count() << endl;//原指向make_shared<int>(7)被销毁
3)shared_ptr自动销毁所管理的对象
4)shared_ptr会自动释放相关联的内存
举个例子:
auto p= make_shared<int>(7);
cout << p.use_count() << endl;//输出1
vector< shared_ptr<int>> vec;
vec.emplace_back(p);
cout << p.use_count() << endl;//输出2
vec.pop_back();//等于删除了最后一个元素
cout << p.use_count() << endl;//输出1
5)使用动态生存期的类
使用动态内存的三种原因很重要,需要理解理解
2.动态内存可以方便在多个对象间共享数据
接下来通过举例来说明理解动态内存的这一特性
1)定义StrBlob类
2)StrBlob构造函数
3)元素访问成员函数
4)Str_Blob的拷贝、赋值和销毁
3.直接管理内存
1)使用new动态分配和初始化对象
auto s = new auto("123");
auto c = new auto('a');
auto i = new auto(2);
2)动态分配的const对象
const更加复杂了起来。
3)内存耗尽
即说明指针如何处理内存耗尽的情况。
4)释放动态内存
5)指针值和delete
6)动态对象的生存期直到被释放时为止
7)delete之后重置指针值
注意: 只是释放了空间,但是指针是还存在的,这时候指针处于空悬状态。
auto s = new auto("123");
delete s;
cout << *s;//处于空悬状态,报错
8)空指针与空悬指针
4.shared_ptr和new结合使用
1)不要混合使用普通指针和智能指针
2)不要使用get初始化另一个智能指针或为智能指针赋值
shared_ptr<int> p(new int(5));
int* p1 = p.get();//此时p跟p1都指向同一个空间
cout << *p1 << endl<<p.use_count()<<endl;
delete p1;
cout<< p.use_count() << endl;//将会报错
3)其他share_ptr操作
5.智能指针和异常
1)智能指针和哑类
关于哑类,参考:C++中的哑类_lenfien的博客-CSDN博客
2)使用自己的释放操作
6.unique_ptr
由于unique_ptr只允许一个指针指向该空间,因此主要通过reset与release功能进行赋值或指针转移。
1)传递unique_ptr参数和返回unique_ptr
这两种情况可以视为unique_ptr的使用特例。
2)向unique_ptr传递删除器
关于传递删除器这里讲的不太清楚,例子不够明显,要了解可参考:[C++11]独占的智能指针unique_ptr的删除器_m0_51955470的博客-CSDN博客
7.weak_ptr
关键:lock函数
1)核查指针类
这个例子举得感觉不太好,首先就是这个例子是衔接之前的例子的,然而之前的例子都忘得差不多了。
2)指针操作
二、动态内存
1.new和数组
1)分配一个数组会得到一个元素类型的指针
2)初始化动态分配对象的数组
使用举例:
void dynamiAarray(int n)
{
int* p = new int[n] {1,2,3,4};//n大于4剩下补0,小于4截断。但是危险
//cout<<p[2]//将输出3
for (int* q = p; q != p + n; ++q)cout << *q<<endl;
}
void main()
{
dynamicarray(2);//打印1 2
dynamicarray(6);1 2 3 4 0 0
}
3)动态分配一个空数组是合法的
4)释放动态数组
总结:注意加方括号。
5)智能指针和动态数组
采用unique_ptr可以方便安全地管理动态数组。
使用share_ptr管理动态数组相当地麻烦又容易出错。
2.allocator类
1)allocator类
2)allocator分配未构造的内存
感觉这allocate用起来也太麻烦了点。
3)拷贝和填充未初始化的内存的算法
三、使用标准库:文本查询程序
这一块是在通过举个比较大例子说明整个标准库设施。等后面抽个空再把整个例子做一遍。