本小节讲智能指针模版类。
智能指针是行为类似于指针的类对象。
void remodel(std::string &str)
{
string * ps=new string(str);
...
str=*ps;
return;
}
每当调用的时候,该函数都会分配堆中的内存,但从不收回,从而导致内存泄漏。
解决之道就是可以在return语句之前添加下面的delete语句,即可
delete ps;这样就可以释放内存了。
但是,涉及到别忘了,实际中就会发生忘记的情况,不是最佳的解决方案。来看看需要怎么做呢?
当remodel()这样的函数终止的时候,本地变量都将从栈内存中删除。因此,指针ps占据的内存将被释放,如果ps指向的内存也被释放,该有多好!,如果ps有一个析构函数,该析构函数在ps过期的时候释放它所指向的内存。因此,ps的问题在于它只是一个常规的指针,它不是具有析构函数的对象。如果它是对象,那么对象过期的时候,让它的析构函数删除指向的内存。这就是:auto_ptr 、unique_ptr、shared_ptr 背后的思想。auto_ptr 是C++98提供的解决方案,C++11已经将它抛弃,并提供了另外的两种解决方案。
这三个智能指针模版(auto_ptr 、unique_ptr、shared_ptr)都定义了类似指针的对象,可以将new获得(直接或者间接)的地址赋给这种对象。当智能指针过期时,其析构函数将使用delete来释放内存,自动就释放了。
要创建智能指针对象,必须包含投文件memory,该文件包括模版定义。
程序清单16.5 smrtptrs.cpp
// Example16.5_smrtptrs.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include <memory>
using std::cout;
class Report
{
private:
std::string str;
public:
Report(const std::string s) :str(s)
{
cout << "Object Created!\n";
}
~Report(){cout<< "Object Deleted!\n";}
void comment()const{ cout << str<<"\n"; }
};
int main()
{
// std::cout << "Hello World!\n";
{
std::auto_ptr<Report> ps(new Report("Using auto_ptr"));
ps->comment();//use -> to invoke a member function
}
{
std::shared_ptr<Report> ps(new Report("Using shared_ptr"));
ps->comment();//use -> to invoke a member function
}
{
std::unique_ptr<Report> ps(new Report("Using unique_ptr"));
ps->comment();//use -> to invoke a member function
}
}
结果:
Object Created!
Using auto_ptr
Object Deleted!
Object Created!
Using shared_ptr
Object Deleted!
Object Created!
Using unique_ptr
Object Deleted!
这三个种,auto_ptr 已经过时,unique和share的使用还是有一些区别,具体在这里不展开了,掌握这种思想很重要,析构函数中释放内存这样真不错。