智能指针使用注意点

一、unique_ptr转到shared_ptr注意点

#include <iostream>
#include <memory>

using namespace std;


std::unique_ptr<std::string> foo()
{
	return std::make_unique<std::string>("foo");
}

int main()
{

	std::shared_ptr<std::string> sp1 = foo();//发生了移动语义,不是拷贝
	printf("%s\n",sp1->c_str());

	auto up = std::make_unique<std::string>("Hello World");

	std::shared_ptr<std::string> sp2 = std::move(up);
	//std::shared_ptr<std::string> sp3 = up; 错误不能直接赋值,需要转移所有权 std::move(up)

	if (sp2.unique())//判断是不是只有一个在占用
		cout << "only 1 count" << endl;

	system("pause");
	return 0;

}

在这里插入图片描述

二、循环引用与解决

#include <iostream>
#include <memory>

using namespace std;



struct BClass;

struct AClass
{
	shared_ptr<BClass> pb;
	~AClass() { std::cout << "~AClass()\n"; }
};

struct CClass;

struct BClass
{
	shared_ptr<AClass> pa;
	~BClass() { std::cout << "~BClass()\n"; }
};

struct CClass
{
	shared_ptr<AClass> pa;
	~CClass() { std::cout << "~CClass()\n"; }
};

int main()
{
	{
		auto a = std::make_shared<AClass>();
		auto b = std::make_shared<BClass>();
		auto c = std::make_shared<CClass>();

		// 循环引用
		a->pb = b;//b ref 2
		b->pa = a;//a ref 2

		c->pa = a;//a ref 3,c ref 1
		// c 释放

		//c.reset();
		std::cout << "计数: " << a.use_count() << "\n";
		std::cout << "计数: " << b.use_count() << "\n";
		std::cout << "计数: " << c.use_count() << "\n";


	}
	system("pause");
	return 0;

	// a, b 仍然相互持有
}

结果:
在这里插入图片描述
解决方法如下(使用weak_ptr):

struct AClass
{
	weak_ptr<BClass> pb;
	~AClass() { std::cout << "~AClass()\n"; }
};

struct CClass;

struct BClass
{
	weak_ptr<AClass> pa;
	~BClass() { std::cout << "~BClass()\n"; }
};

结果:
在这里插入图片描述

三、weak_ptr的使用

weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快。表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。

#include <iostream>
#include <memory>

using namespace std;


int main() {
	{
		std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
		std::cout << sh_ptr.use_count() << std::endl;  // 输出1

		std::weak_ptr<int> wp(sh_ptr);
		std::cout << wp.use_count() << std::endl;  // 赋值给weak_ptr后还是输出1

		if (!wp.expired()) { // 检查sh_ptr是否还有效
			std::shared_ptr<int> sh_ptr2 = wp.lock(); //将sh_ptr赋值给sh_ptr2
			*sh_ptr = 100;
			std::cout << wp.use_count() << std::endl;  // 输出2
		}
	} //delete memory

	std::weak_ptr<int> wp;
	{
		std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
		wp = sh_ptr;
		std::cout << std::boolalpha << wp.expired() << std::endl;  // 输出false,引用对象还没删除
	} //delete memory

	std::cout << std::boolalpha << wp.expired() << std::endl;  // 输出true,引用对象已经删除

	system("pause");
	return 0;
}

结果:
在这里插入图片描述

参考链接:https://blog.csdn.net/sinat_31608641/article/details/107702175

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发如雪-ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值