十三、指针和引用(三)
十三、指针和引用(三)
1、std::unique_ptr(唯一智能指针)
1)概念
std::unique_ptr是所谓的智能指针的一种,主要目的是为了解决原生指针安全性不足的弊端
//std::unique_ptr指针的声明语法
std::unqiue_ptr<类型>变量名称{};
//示例
std::unique_ptr<int>ptrA{std::make_unique<int>(150)}; // 申请一个具有1个int类型大小的指针,值为150
std::cout<<*ptrA; //指针使用
std::unique_ptr<int[]>ptrB{new int[5]}; //C++14之前的写法,申请一个具有5个int类型大小的指针
std::unique_ptr<int[]>ptrB{std::make_unique<int[]>(10)}; //申请一个具有5个int类型大小的指针
ptrB[0]=250; //指针使用,此声明方法,只能通过数组访问
2)唯一智能指针特性
std::unique_ptr的特点是该指针具有唯一性,因此无法让两个std::unique_ptr指针存放相同的内存地址,如下:
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
std::unique_ptr<int>ptrB{};
//ptrA=ptrB; //错误,无法直接赋值
#include <iostream>
int main()
{
int* a = new int[5];
std::unique_ptr<int[]>intptr{ std::make_unique<int[]>(5) }; //申请一个具有5个int类型大小的指针
std::unique_ptr<int>intptrA{ std::make_unique<int>(5) }; // 申请一个具有1个int类型大小的指针,值为5
std::cout << intptr << " " << intptr[0]<<std::endl; //013D5C98 0
std::cout << intptrA << " " << *intptrA << std::endl; //013DEC10 5
}
3)reset()用法
reset将会释放std::unique_ptr的内存空间,并且将std::unique_ptr设置为nullptr;
//reset()用法示例
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
ptrA.reset(); //此时ptrA的内存空间被释放,ptrA的值设置成了nullptr
//reset()示例
#include <iostream>
int main()
{
int* a = new int[5];
delete[] a; //释放new申请的内存空间
std::unique_ptr<int>ptrA{ std::make_unique<int>(100) };
std::cout << "释放内存前的地址:"<<ptrA << std::endl;
ptrA.reset(); //释放唯一智能指针
std::cout << "释放内存后的地址:" << ptrA << std::endl;
}
4)get()用法:返回一个std::unique_ptr的指针
//get()用法
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
int*p = ptrA.get(); //相当于将ptrA申请时的内存赋值给p
5)release()用法
relsease将会返回std::unique_ptr的指针,并且将std::unique_ptr设置为nullptr,但是注意release并不会释放其占用的内存空间
//relseae()用法
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
int* p = ptrA.release();
//此时ptrA占用的内存空间没有被释放,ptrA的值设置成了nullptr,p等于ptrA申请内存时的地址
//release只是将申请的内存地址设置为了0,并没有释放,并且将原理的地址进行了返回
#include <iostream>
int main()
{
int* a = new int[5];
std::unique_ptr<int>ptrA{ std::make_unique<int>(100) };
std::cout << "release前的地址:" << ptrA << std::endl;
a = ptrA.release();
std::cout << "release后的地址:" << ptrA << std::endl;
std::cout << "a的地址:" << a << std::endl;
}
6)唯一智能指针的转移(move)
std::unique_ptr指针因为具有唯一性,因此不能被复制,但是可以转移
//唯一智能指针转移语法
转移后的指针变量=std::move(转移前的指针变量);
//示例
std::unique_ptr<int>ptrA{std::make_unique<int>(150)};
std::unique_ptr<int>ptrB;
ptrB=std::move(ptrA); //将ptrA的地址转移到ptrB,转移后ptrA被设置为nullptr
2、std::shared_per(共享智能指针)
1)共享智能指针语法
//共享智能指针语法
std::shared_ptr<类型>变量名称{};
//示例
std::shared_ptr<int>ptrA{};
std::shared_ptr<int>ptrB{std::make_shared<int>(5)};
//注:std::make_shared不支持新式的数组的定义方式,只能通过new的方式
std::shared_ptr<int[]>ptr{new int[5]{1,2,3,4,5}};
//共享智能指针的定义及使用
#include <iostream>
int main()
{
int* a{};
std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
std::shared_ptr<int>ptrB{ ptrA }; //共享ptrA的内存地址
std::shared_ptr<int>ptrC{ ptrA };
std::cout << "ptrA的内存地址为:" << ptrA << std::endl;
std::cout << "ptrB的内存地址为:" << ptrB << std::endl;
std::cout << "ptrA的内存地址为:" << ptrC << std::endl;
std::cout << "\n";
std::cout << "ptrA的值为:" << *ptrA << std::endl;
std::cout << "ptrB的值为:" << *ptrB << std::endl;
}
2)共享智能指针特性
可以有多个std::shared_ptr指向同一地址,同一地址下只有当最后一个std::shared_ptr释放的时候,才会释放其占用的内存空间,std::shared_ptr会记录当前地址有多少个智能指针调用
3)统计共享指针当前有多少个对象调用(use_count)
//统计共享指针当前有多少个对象调用
long std::shared_ptr.use_count();
.user_count(); //会返回当前指针共有多少个对象调用
//use.count()用法示例
#include <iostream>
int main()
{
int* a{};
std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
std::shared_ptr<int>ptrB{ ptrA }; //共享ptrA的内存地址
std::shared_ptr<int>ptrC{ ptrA };
std::cout << "ptrA指针共有多少个指针调用:" << ptrA.use_count() << std::endl;
}
5)判断共享智能指针是否唯一(unique)
//判断共享智能指针是否唯一
bool std::shared_ptr.unique();
//unique()返回一个bool值,如果当前智能指针是唯一拥有该指针的,那么返回true,负责返回false
注:C++17标准无法使用该函数,只能在17之前使用
//unique()用法
#include <iostream>
int main()
{
int* a{};
std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
std::cout << "判断指针指针ptrA是否唯一:" << ptrA.unique() << std::endl;
std::shared_ptr<int>ptrB{ ptrA }; //共享ptrA的内存地址
std::shared_ptr<int>ptrC{ ptrA };
std::cout << "判断指针指针ptrA是否唯一:" << ptrA.unique() << std::endl;
}
4)共享智能指针的释放
reset()会将当前共享指针设置为nullptr,同时如果当前智能指针是最后一个拥有该指针的对象,那么将会释放内存。只有最后一个指针变量释放,才能释放内存空间
//共享智能指针的释放
std::shared_ptr.reset();
//reset()使用
#include <iostream>
int main()
{
int* a{};
std::shared_ptr<int>ptrA{ std::make_shared<int>(5) };
std::shared_ptr<int>ptrB{ ptrA }; //共享ptrA的内存地址
std::shared_ptr<int>ptrC{ ptrA };
ptrB.reset(); //只是修改指针的指向,并不释放指针内存地址
std::cout << ptrB << std::endl;
ptrA.reset();
std::cout << ptrA << std::endl;
std::cout << ptrC << std::endl;
ptrC.reset(); //释放智能指针的内存地址
std::cout << ptrC << std::endl;
}
热门相关:都市捉妖人 试婚老公,用点力! 龙骑战机 重生复仇:腹黑千金不好惹 觅仙道