我是靠谱客的博主 殷勤航空,最近开发中收集的这篇文章主要介绍智能指针,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

1、智能指针

2、shared_ptr

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");
}

 

最后

以上就是殷勤航空为你收集整理的智能指针的全部内容,希望文章能够帮你解决智能指针所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部