C++ 智能指针

简介

C++11 智能指针


前言

一、什么是智能指针?

shared_ptr 强智能指针,可以改变资源的引用计数
weak_ptr 弱智能指针,不会改变资源的引用计数
unique_ptr 独占式智能指针,只能转移,不能赋值

二、智能指针的原理

shared_ptr采用了引用计数器,允许多个指针指向同一个对象。每一个shared_ptr的拷贝都指向相同的内存,并共同维护同一个引用计数器,记录同一个实例被引用的次数。每使用他一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。

三、什么是智能指针循环引用?

1.未循环引用情况

1.1 代码如下

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest 构造成功!" << endl;
	}
	~ATest(){
		cout << "ATest 析构成功!" << endl;
	}
public:
	shared_ptr<B> m_bptr;     //引用
};

class BTest
{
public:
	BTest(){
		cout << "BTest 构造成功!" << endl;
	}
	~BTest(){
		cout << "BTest 析构成功!" << endl;
	}
	
public:
	shared_ptr<A> m_aptr;   //引用
};
//使用
void test01()
{
	shared_ptr<ATest> pa(new ATest());
	shared_ptr<BTest> pb(new BTest());

	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

1.2 结果如下

在这里插入图片描述
表明,ATest和BTest两个类的析构函数正常调用,表明内存正确释放。

2.循环引用情况

2.1 代码如下

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest 构造成功!" << endl;
	}
	~ATest(){
		cout << "ATest 析构成功!" << endl;
	}
public:
	shared_ptr<B> m_bptr;     //引用
};

class BTest
{
public:
	BTest(){
		cout << "BTest 构造成功!" << endl;
	}
	~BTest(){
		cout << "BTest 析构成功!" << endl;
	}
	
public:
	shared_ptr<A> m_aptr;   //引用
};
//使用
void test02()
{
	shared_ptr<ATest> pa(new ATest()); //使用
	shared_ptr<BTest> pb(new BTest()); //使用

	pa->m_bptr = pb;  
	pb->m_aptr = pa;
	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
}
int main()
{
	test02();
	system("pause");
	return 0;
}

2.2 结果如下

在这里插入图片描述
表明,ATest和BTest两个类的析构函数未调用,表明内存未正确释放。

四、智能指针循环引用会导致什么问题?

如上2.2结果所示,智能指针的循环引用会造成new出来的资源无法释放,导致内存泄露问题。

五、怎么解决智能指针循环引用问题?

1.方法

定义对象的时候,用强智能指针;引用对象的地方,用弱智能指针

2. 代码如下

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest 构造成功!" << endl;
	}
	~ATest(){
		cout << "ATest 析构成功!" << endl;
	}
public:
    //将shared_ptr改为了weak_ptr
	weak_ptr<B> m_bptr;      //引用
};

class BTest
{
public:
	BTest(){
		cout << "BTest 构造成功!" << endl;
	}
	~BTest(){
		cout << "BTest 析构成功!" << endl;
	}
	
public:
    //将shared_ptr改为了weak_ptr
	weak_ptr<A> m_aptr;      //引用
};
//使用
void test03()
{
	shared_ptr<ATest> pa(new ATest()); //使用
	shared_ptr<BTest> pb(new BTest()); //使用

	pa->m_bptr = pb;  
	pb->m_aptr = pa;
	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
}
int main()
{
	test02();
	system("pause");
	return 0;
}

3. 结果

在这里插入图片描述
结果,与《未循环引用情况》一致,表明,资源正确释放。

六、成员方法调用问题

1. 场景

2. 代码如下

#include<iostream>
#include<string>
#include<memory>
using namespace std;
/*
*/
class BTest;
class ATest
{
public:
	ATest(){
		cout << "ATest 构造成功!" << endl;
	}
	~ATest(){
		cout << "ATest 析构成功!" << endl;
	}

	void funA()
	{
		cout << "ATest对象的fun方法!" << endl;
	}
public:
	weak_ptr<BTest> m_bptr;     //引用
};

class BTest
{
public:
	BTest(){
		cout << "BTest 构造成功!" << endl;
	}
	~BTest(){
		cout << "BTest 析构成功!" << endl;
	}
	void funB()
	{
		shared_ptr<ATest> usptr = m_aptr.lock();  //提升方法
		if (usptr!=nullptr)
		{
			usptr->funA();
		}
		//m_aptr->funA();    // 弱智能指针不能调用
	}
public:
	weak_ptr<ATest> m_aptr;   //引用
};
void test04()
{
	shared_ptr<ATest> pa(new ATest()); //使用
	shared_ptr<BTest> pb(new BTest()); //使用

	pa->m_bptr = pb;
	pb->m_aptr = pa;
	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;

	pb->funB();
}
int main()
{
	test04();
	system("pause");
	return 0;
}

3. 结果

在这里插入图片描述
成功调用。

总结

weak_ptr与shared_ptr配合使用。

待完善。。。。。

《C++智能指针——shared_ptr的使用》

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值