概述
目录
1、智能指针
3、weak_ptr
4、unique_ptr
1、智能指针
在C++中,内存管理是用new和delete来实现的。
1)new:为对象分配一块内存空间;
2)delete:释放new开辟的空间。
内存使用中经常会出现两种问题:
1)一块在使用的内存,被释放掉;
2)不再使用的内存未被释放;
为解决这两个问题引入了智能指针的概念:它会自动释放不再使用的内存未被释放。
2、shared_ptr
1)概念
shared_ptr<>实现多个智能指针可以指向同一个对象,该对象和其相关资源会在最后一个引用被销毁时被释放掉。
2)函数
shared_ptr<T> sp; 默认构造
shared_ptr<T> sp(ptr); 建立一个shared_ptr,初始化为ptr
shared_ptr<T> sp(ptr,del); 初始化ptr,析构函数为del
shared_ptr<T> sp(ptr,del,ac); 初始化ptr,析构del用ac作为内存分配器
shared_ptr<T> sp(nullptr);
shared_ptr<T> sp(nullptr,ptr);
shared_ptr<T> sp(nullptr,ptr,del);
shared_ptr<T> sp(sp2); 与sp2共享使用
shared_ptr<T> sp(move(sp2)); 夺取sp2的使用权,sp2置空
shared_ptr<T> sp(sp2,ptr); 共享sp2,指向ptr
shared_ptr<T> sp(wp); 基于weak pointer wp创建的sp
shared_ptr<T> sp(move(up)); 基于unique_ptr up创建的sp
shared_ptr<T> sp(move(ap)); 基于auto_ptr up创建的sp
sp.~shared_ptr(); 析构
sp = sp2; 共享sp2
sp = move(sp2); sp2将拥有权交给sp,sp2 = nullptr
sp = move(up); up将拥有权交给sp,up= nullptr
sp = move(ap); ap将拥有权交给sp,ap= nullptr
sp.swap(sp2); 置换sp1和sp2的pointer和delete
swap(sp1,sp2); 置换sp1和sp2的pointer和delete
sp.reset(); 放弃拥有权并重新初始化,赋值为空
sp.reset(ptr); 放弃拥有权,重新初始化为ptr
sp.reset(ptr,del);
make_shared(...); 为一个新的对象建立对象
allocate_shared(ac,...); 为新对象建立一个对象,使用allocate ac
sp.get(); 返回存储的pointer(通常为被拥有物的地址)
sp.use_count(); 返回共享对象的拥有者数量
sp.unique(); 返回sp是否是唯一拥有者 等同于 sp.use_count == 1
if(sp); 判断sp是否为空
sp1 == sp2 针对pointer 调用 ==
sp1 != sp2 针对pointer 调用 !=
sp1 <= sp2 针对pointer 调用 <=
sp1 >= sp2 针对pointer 调用 >=
sp1 < sp2 针对pointer 调用 <
sp1 > sp2 针对pointer 调用 >
static_pointer_case(sp); 对sp执行static_case<>
dynamic_pointer_case(sp); 对sp执行dynamic_case<>
const_pointer_case(sp); 对sp执行const_case<>
get_deleter(sp); 返回delete地址
sp.owner_befor(wp); 提供自己与 weak poinrter之间的strict weak ording
3)高层接口(线程安全)
atomic_is_lock_free(&sp); 如果sp的atomic接口是lock free 返回true
atomic_load(&sp); 返回sp
atomic_store(&sp,sp2); 将sp2赋值给sp
atomic_exchange(&sp,sp2); 交换sp和sp2的值
4)测试
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
int main()
{
//创建
shared_ptr<string> pA(new string("AAA"));
shared_ptr<string> pB(new string("BBB"));
shared_ptr<string> pC;
//只能共享指针 赋值共享指针,不允许隐式转换 string 赋值共享指针
//pC = new string("CCC");
pC = pA;
//自定义delete
{
shared_ptr<string> pE(new string("ABCDE"), [](string *p) {
cout << "delete " << *p << endl;
delete p;
});
//获取智能指针的del
auto del = [](string *p) {
cout << "delete " << *p << endl;
delete p;
};
shared_ptr<string> pF(new string("FFF"), del);
decltype(del) *pd = get_deleter<decltype(del)>(pF);
shared_ptr<string> pG(new string("GGG"), *pd);
}
//创建一个新的共享对象给pC
pC = make_shared<string>("CCC");
cout << "make_shared<string>("CCC") " <<*pC << endl;
string *str = new string("DDD");
//重置 为 str
pC.reset(str);
cout << "reset(str) " << *pC << endl;
cout << "共享对象个数 " << pC.use_count() << endl;
//改值
(*pA)[0] = 'C';
pB->replace(0, 1, "D");
//存智能指针
vector<shared_ptr<string>> vec;
vec.emplace_back(pA);
vec.emplace_back(pA);
vec.emplace_back(pB);
vec.emplace_back(pA);
for ( auto ptr : vec)
{
cout << *ptr << ends;
}
cout << endl;
//更改数据
*pA = "CCC";
for (auto ptr : vec)
{
cout << *ptr << ends;
}
cout << endl;
system("pause");
}
3、weak_ptr
weak_ptr用来共享对象但不拥有对象(不能对对象进行查看、更改等操作)。不计共享次数
1)weak_ptr可以为空
创建未赋值;对象最后一个shared_ptr被删除。
2)函数
weak_ptr<T> wp; 默认构造
weak_ptr<T> wp(sp); 共享被sp拥有的pointer的拥有权
weak_ptr<T> wp(wp2); 共享被wp2拥有的pointer的拥有权
wp.~weak_ptr(); 析构,销毁weak_ptr但不影响它所拥有的的对象
wp = wp2; 赋值
wp = sp; 赋值
wp.swap(wp2); 置换
swap(wp1,wp2);
wp.reset(); 放弃被拥有物的拥有权
wp.use_count(); 返回拥有者shared_ptr的数量。如果weak_ptr等于空返回0
wp.expired(); 返回 是否为空
wp.lock(); 返回一个shared_ptr
wp.owner_before(wp2); 提供自己与另一个weak_ptr之间的 strict weak ordering
wp.owner_before(sp); 提供自己与另一个shared_ptr之间的 strict weak ordering
3)测试
#include <iostream>
#include <string>
#include <memory>
using namespace std;
int main()
{
auto del = [](string *p) { cout << *p << endl; delete p; };
shared_ptr<string> pA(new string("AAA"), del);
cout << "*pA "<<*pA << endl;
weak_ptr<string> wp;
cout << "Whether weak_ptr is empty : " << wp.expired() << endl;
wp = pA;
cout << " use_count "<<wp.use_count() << endl;
//返回一个shared_ptr对象
shared_ptr<string> pB = wp.lock();
cout << " use_count " << wp.use_count() << endl;
pA.reset();
pB.reset();
cout << "pA.reset() and pB.reset()." << endl;
cout << "Whether weak_ptr is empty : " << wp.expired() << endl;
cout << " use_count " << wp.use_count() << endl;
system("pause");
}
4、unique_ptr
C++11提供的,一种在异常发生时可以避免资源泄露的智能指针。它确保一个资源在同一时间只被一个pointer所拥有。当指针被销毁、空、或指向别处时,先前拥有的对象被销毁,资源被释放。
1)函数
unique_ptr<...> up; 默认构造
unique_ptr<...> up(nullptr); 建立一个空的unique_ptr
unique_ptr<...> up(ptr); 建立unique_ptr,初始化为ptr
unique_ptr<...> up(ptr,del); 建立unique_ptr,初始化为ptr,析构为del
unique_ptr<...> up(move(up2)); up取代up2,up2为空
unique_ptr<...> up(move(ap)); up取代ap,ap为空
up.~unique_ptr(); 析构
up = move(up2);
up = nullptr;
up1.swap(up2);
swap(up1,up2);
up.reset(); 刷新,置空
up.reset(ptr); 刷新,置为ptr
up.release(); 放弃拥有权,不调用delete
up.get(); 返回pointer
if(up); 判断是否为空
up1 == up2;
up1 != up2;
up1 <= up2;
up1 >= up2;
up1 < up2;
up1 > up2;
up.get_deleter(); 放回del的引用
2)测试
#include <iostream>
#include <string>
#include <memory>
using namespace std;
int main()
{
//自定义 del
auto del = [](string *p) { cout << *p << endl; delete p; };
{
//创建
unique_ptr<string, decltype(del)> pA(new string("AAA"), del);
}
{ //数组类型的声明方式 delete[]
unique_ptr<string[]> pB(new string[10]);
//针对数组,不再提供*和->,改用[]
//默认析构 delete[]
//不支持不同类型之间的转换。不允许指向派生元素类型
}
string *str = new string("CCC");
unique_ptr<string> pC(str);
pC.release(); //放弃拥有权,不调用delete
cout << *str << endl;
system("pause");
}
最后
以上就是殷勤航空为你收集整理的智能指针的全部内容,希望文章能够帮你解决智能指针所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复