1、为什么需要智能指针
智能指针是为了解决内存泄漏问题
内存泄漏问题,本质上是因为程序员自己忘记主动释放导致的
智能指针的解决思路是:连带自动释放
2、智能指针的本质工作原理
(1)一方面,利用局部变量/对象分配在栈上,代码段结束时会自动释放的特性
(2)另一方面,利用对象释放时会自动调用析构函数的特性
3.智能指针的使用实例
使用代码如下:
# include<iostream>
#include <memory>
using namespace std;
class Ball
{
public: Ball()
{
cout<<"A ball appears."<< endl;
}
~Ball()
{
cout<<"A ball disappears."<< endl;
}
void Bounce()
{
cout<<"A ball jumps."<<endl;
}
};
int main()
{
//创建共享p指针指向Ball
shared_ptr <Ball> p=make_shared<Ball>();
//输出p共享指针的使用次数
cout<<p. use_count()<< endl;
//创建共享p2指针指向Ball
shared_ptr <Ball>p2=p;
//输出p,p2共享指针的使用次数
cout<<p. use_count()<<""<<p2. use_count()<< endl;
//创建共享p3指针指向Ball
shared_ptr <Ball>p3=p;
//输出p,p2,p3共享指针的使用次数
cout <<p. use_count()<<""<<p2. use_count()<<p3. use_count()<<endl;
//释放P
p. reset();
//释放P2
p2. reset();
//释放P3
p3. reset();
}
运行以上代码后实际的运行结果如下:
在实际使用时,将后面的三句指令屏蔽后也是相同的的效果。
# include<iostream>
#include <memory>
using namespace std;
class Ball
{
public: Ball()
{
cout<<"A ball appears."<< endl;
}
~Ball()
{
cout<<"A ball disappears."<< endl;
}
void Bounce()
{
cout<<"A ball jumps."<<endl;
}
};
int main()
{
//创建共享p指针指向Ball
shared_ptr <Ball> p=make_shared<Ball>();
//输出p共享指针的使用次数
cout<<p. use_count()<< endl;
//创建共享p2指针指向Ball
shared_ptr <Ball>p2=p;
//输出p,p2共享指针的使用次数
cout<<p. use_count()<<""<<p2. use_count()<< endl;
//创建共享p3指针指向Ball
shared_ptr <Ball>p3=p;
//输出p,p2,p3共享指针的使用次数
cout <<p. use_count()<<""<<p2. use_count()<<p3. use_count()<<endl;
//释放P
//p. reset();
//释放P2
//p2. reset();
//释放P3
//p3. reset();
}
运行以上代码后实际的运行结果如下:
在实际使用时以上代码中的.reset()函数,可以在该函数(方法)中添加新的成员变量,使智能指针指向一个新的同类的地址,代码如下。
# include<iostream>
#include <memory>
using namespace std;
/*************测试使用Ball******************/
class Ball
{
public: Ball()
{
cout<<"A ball appears."<< endl;
}
~Ball()
{
cout<<"A ball disappears."<< endl;
}
void Bounce()
{
cout<<"A ball jumps."<<endl;
}
};
/*************测试使用Ball2******************/
class Ball2
{
public: Ball2()
{
cout<<"A ball2 appears."<< endl;
}
~Ball2()
{
cout<<"A ball2 disappears."<< endl;
}
void Bounce2()
{
cout<<"A ball2 jumps."<<endl;
}
};
int main()
{
//创建共享p指针指向Ball
shared_ptr <Ball> p=make_shared<Ball>();
//输出p共享指针的使用次数
cout<<p. use_count()<< endl;
//创建共享p2指针指向Ball
shared_ptr <Ball>p2=p;
//输出p,p2共享指针的使用次数
cout<<p. use_count()<<""<<p2. use_count()<< endl;
//创建共享p3指针指向Ball
shared_ptr <Ball>p3=p;
//输出p,p2,p3共享指针的使用次数
cout <<p. use_count()<<""<<p2. use_count()<<p3. use_count()<<endl;
p. reset(new Ball);
// p2. reset();
// p3. reset();
}
运行结果:
运行了两次析构,说明我们释放了两个Ball类的内存。
在实际使用时可以考虑我们是否可以指向别的类,比如上面的Ball2,实际是不行的,在我们定义智能指针时,它的数据类型就已经被确定了,我们不能再修改它的数据类型了。
4.使用时注意事项
在使用时当我们使用裸指针和智能指针指向同一个地址时,当我们将智能指针都删除后,裸指针所指向的内存也不复存在,但裸指针还存在,这时再次调用裸指针有可能发生不可预料的后果。