智能指针使用注意点

一、unique_ptr转到shared_ptr注意点

#include 
#include 

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 sp3 = up; 错误不能直接赋值,需要转移所有权 std::move(up)

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

	system("pause");
	return 0;

}

在这里插入图片描述

二、循环引用与解决

#include 
#include 

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 仍然相互持有
}

结果:
智能指针使用注意点_第1张图片
解决方法如下(使用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"; }
};

结果:
智能指针使用注意点_第2张图片

三、weak_ptr的使用

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

#include 
#include 

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

结果:
智能指针使用注意点_第3张图片

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

你可能感兴趣的:(C/C++基础,c++)