C++智能指针shared_ptr举例说明
当一个函数使用new动态的申请内存后,那么在不再需要使用这块内存之后,需要使用delete去释放内存。如果忘记释放(程序复杂时容易遗漏),将有可能会出现内存泄漏的问题。
而C++11的新特性智能指针shared_ptr可以很好的规避这个问题,也就是说使用智能指针后,就不用再对new(最好使用make_shared去申请)申请的内存进行delete,智能指针检查自己不被使用之后,会自动释放所指向的内存。下面举例说明:
这里模拟一场考试的流程,首先获取一份试卷,然后由学生来答这份试卷,再交给老师批改,最后销毁这份试卷。
使用普通指针实现代码:
#include<iostream>
#include<memory>
class TestPaper { //试卷类
public:
TestPaper() // 构造函数
{
std::cout<<"TestPaper constructed"<<std::endl;
}
~TestPaper() // 析构函数
{
std::cout<<"TestPaper destroyed\n"<<std::endl;
}
static TestPaper *getInstance()
{
return new TestPaper();
}
};
void student(TestPaper *)
{
std::cout<<"Student do testPaper"<<std::endl;
}
void teacher(TestPaper *)
{
std::cout<<"Teacher check testPaper"<<std::endl;
}
TestPaper *test()
{
TestPaper *tp = TestPaper::getInstance(); // 获取试卷实例
student(tp); // 学生答试卷
teacher(tp); // 老师批改试卷
std::cout<<"Test end"<<std::endl; // 考试结束
return tp; // 返回考过的试卷
}
int main()
{
for (int i=0; i<2; ++i) {
TestPaper *tp_ = test(); // 开始考试
delete tp_; // 必须手动销毁考试过的试卷
// 可以尝试一下不销毁试卷,结果就是这些试卷一直不会
// 被释放,如果继续考试,申请的内存将越来越多,也就
// 是内存泄漏
}
std::cout<<"End"<<std::endl;
return 0;
}
运行结果:
使用智能指针实现代码:
#include<iostream>
#include<memory>
class TestPaper { //试卷类
public:
TestPaper() // 构造函数
{
std::cout<<"TestPaper constructed"<<std::endl;
}
~TestPaper() // 析构函数
{
std::cout<<"TestPaper destroyed\n"<<std::endl;
}
static std::shared_ptr<TestPaper> getInstance()
{
return std::make_shared<TestPaper>();
}
};
void student(std::shared_ptr<TestPaper>)
{
std::cout<<"Student do testPaper"<<std::endl;
}
void teacher(std::shared_ptr<TestPaper>)
{
std::cout<<"Teacher check testPaper"<<std::endl;
}
std::shared_ptr<TestPaper> test()
{
std::shared_ptr<TestPaper> p = TestPaper::getInstance(); // 使用智能指针
// 获取试卷实例
student(p); // 学生答试卷
teacher(p); // 老师批改试卷
std::cout<<"Test end"<<std::endl; // 考试结束
return p; // 返回考过的试卷,如果没有被接收再使用,就自动销毁
}
int main()
{
for (int i=0; i<2; ++i) {
test(); // 开始考试,这里不接收考过的试卷,也不用手动销毁
}
std::cout<<"End"<<std::endl;
return 0;
}
运行结果和上面普通指针实现的是一样的。