C++ 智能指针
为什么需要智能指针?智能指针是什么?
智能指针其作⽤是管理⼀个指针,避免咋们程序员申请的空间,在函数结束时忘记释放,造成内存泄漏这种情况滴发⽣。
(避免new 后 忘记 delete 导致内存泄漏)
然后使⽤智能指针可以很⼤程度上的避免这个问题,因为智能指针就是⼀个类,当超出了类的作⽤域是,类会⾃动
调⽤析构函数,析构函数会⾃动释放资源。所以智能指针的作⽤原理就是在函数结束时⾃动释放内存空间,不需要
⼿动释放内存空间。
#define _CRTDBG_MAP_ALLOC
#include<crtdbg.h>//vs2019 用于检查内存泄露
#include<memory>
#include<iostream>
using namespace std;
void test1()
{
int* p = new int(10);
cout<<*p<<endl;
//由于没有释放new 出得内存空间,会导致内存泄漏
}
void test2()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//智能指针本质是一个类 对象,模拟出指针得特性
string* s = new string("hello");
//给 s 指针添加一个管家sa , 可以使用s指针特性,且会自动delete s,避免出现内存泄漏
auto_ptr<string> sa(s);
cout << *sa << " 元素个数:"<<sa->size() << endl;
}
常用得智能指针:
- auto_ptr : (C++98 的⽅案,C11 已抛弃)采⽤所有权模式
auto_ptr<std::string> p1 (new string ("hello"));
auto_ptr<std::string> p2;
p2 = p1; //auto_ptr 不会报错.
此时不会报错,p2 剥夺了 p1 的所有权,但是当程序运⾏时访问 p1 将会报错。所以 auto_ptr 的缺点是:存在潜
在的内存崩溃问题!
- **unique_ptr: ** (替换 auto_ptr )
unique_ptr 实现独占式拥有或严格拥有概念,保证同⼀时间内只有⼀个智能指针可以指向该对象。它对于避免资
源泄露特别有⽤。
unique_ptr<string> p3 (new string (auto));//#4
unique_ptr<string> p4;//#5
p4 = p3;//此时会报错
编译器认为 p4=p3 ⾮法,避免了 p3 不再指向有效数据的问题。 因此,unique_ptr ⽐ auto_ptr 更安全。
案例:
class Demo
{
public:
Demo(string name,int age)
{
cout << "demo构造函数调用" << endl;
this->m_name = name;
this->m_age = age;
}
~Demo()
{
cout << "demo析构函数调用" << endl;
}
void print()
{
cout << "姓名:" << this->m_name << " 年龄:" <<this->m_age << endl;
}
string m_name;
int m_age;
};
void test2()
{
//创建unique_ptr 智能指针
unique_ptr<string> p3(new string("张三"));
cout << *p3 << endl;
unique_ptr<Demo> UniquePtr = make_unique<Demo>("李四",18);
UniquePtr->print();
unique_ptr<Demo> p2;
}
- shared_ptr: (共享型,强引⽤)
shared_ptr 实现共享式拥有概念,多个智能指针可以指向相同对象,该对象和其相关资源会在==“最后⼀个引⽤被销==
毁”时候释放。从名字 share 就可以看出了资源可以被多个指针共享,它使⽤计数机制来表明资源被⼏个指针共
享。
可以通过成员函数 use_count() 来查看资源的所有者个数,除了可以通过 new 来构造,还可以通过传⼊auto_ptr,
unique_ptr,weak_ptr 来构造。当我们调⽤ release() 时,当前指针会释放资源所有权,计数减⼀。当计数等于 0
时,资源会被释放。
shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性 (auto_ptr 是独占的),在使⽤引⽤计数的机制上提供了
可以共享所有权的智能指针。
weak_ptr: (弱引⽤) 使用较少
weak_ptr 只是提供了对管理对象的⼀个访问⼿段。weak_ptr 设计的⽬的是为配合 shared_ptr ⽽引⼊的⼀种智
能指针来协助 shared_ptr ⼯作,它只可以从⼀个 shared_ptr 或另⼀个 weak_ptr 对象构造,,它的构造和析构不会
引起引⽤记数的增加或减少。
weak_ptr 是⽤来解决 shared_ptr 相互引⽤时的死锁问题,如果说两个 shared_ptr 相互引⽤,那么这两个指针的
引⽤计数永远不可能下降为0,也就是资源永远不会释放。它是对对象的⼀种弱引⽤,不会增加对象的引⽤计数,
和 shared_ptr 之间可以相互转化,shared_ptr 可以直接赋值给它,它可以通过调⽤ lock 函数来获得
shared_ptr。
引⽤时的死锁问题,如果说两个 shared_ptr 相互引⽤,那么这两个指针的
引⽤计数永远不可能下降为0,也就是资源永远不会释放。它是对对象的⼀种弱引⽤,不会增加对象的引⽤计数,
和 shared_ptr 之间可以相互转化,shared_ptr 可以直接赋值给它,它可以通过调⽤ lock 函数来获得
shared_ptr。