1.auto_ptr、unique_ptr、shared_ptr智能指针
这三个智能指针模板都定义了类似指针的对象,可以将new获得(直接或间接)的地址赋给这些对象。当智能指针过期时,其析构函数将使用delete来释放内存。要创建智能指针对象,必须包含头文件<memory>,该文件包含模板定义。然后使用通常的模板语法来实例化所需类型的指针。例如:
//auto_ptr模板类
template<class T>class auto_ptr{
public:
explicit auto_ptr(T* p = 0) throw(); //throw()意味着构造函数不会引发异常
//(已被C++标准摒弃)
.....
};
auto_ptr<double> pd(new double); //pd是一个指向double的智能指针类型,代替double *pd使用
auto_ptr<string> ps(new string); //ps是一个指向string的智能指针,代替string *ps使用
(new double)是 new 返加的指针,指向新分配的内存块。它作为构造函数auto_ptr<double>的参数,即对应于原型中形参p的实参。其它两种智能指针使用同样的语法。
示例:演示了三种智能指针的简单用法,其中每个智能指针都放在一个代码块中,离开代码块时,指针将过期。注意:智能指针模板们于名称空间std中。
//smart_ptr.cpp -----三种智能指针的简单用法
//shared_ptr 和 unique_ptr需要编译器支持C++11标准
#include <iostream>
#include <string>
#include <memory>
class Report{
private:
std::string str;
public:
Report(const std::string s) : str(s){
std::cout<<"Report类被创建!\n";
}
~Report(){std::cout<<"Report 类被销毁!\n";}
void comment() const{std::cout<<str<<"\n";}
};
int main(){
{
std::auto_ptr<Report> ps(new Report("使用auto_ptr智能指针"));//auto_ptr已被C++标准弃用
ps->comment(); //使用->来调用成员函数
}
{
std::shared_ptr<Report> ps(new Report("使用shared_ptr智能指针"));
ps->comment();
}
{
std::unique_ptr<Report> ps(new Report("使用unique_ptr智能指针"));
ps->comment();
}
return 0;
}
所有的指针类都有一个explicit构造函数,该构造函数将指针作为参数,因此不会隐式地将普通指针转换为智能指针。
shared_ptr<double> pd; //智能指针类型
double *p_normal = new double; //普通double*指针
pd = p_normal; //不允许 (隐式转换)
pd = shared_ptr<double>(p_normal); //允许 (显式转换)
shared_ptr<double pshared = p_normal; //不允许(隐式转换)
shared_ptr<double> pshared(p_normal); //允许 (显式转换) p_normal作为智能指针构造函数的参数
2.选择智能指针
如果程序要使用多个指向同一个对象的指针,应选择shared_ptr。这样的情况包括:有一个指针数组,并使用一些辅助指针来标识特定的元素,如最大的元素和最小的元素;两个对象包含都指向第三个对象的指针;以及包含指针的STL容器,很多STL算法都支持复制和赋值操作,这些操作可用于shared_ptr,但不能用于unique_ptr(编译器发出警告)和auto_ptr(行为不确定)。
如果程序不需要多个指向同一个对象的指针,则可使用unique_ptr。如果函数使用new分配内存,并返回指向该内存的指针,将其返回类型声明为unique_ptr是不错的选择。
auto_ptr已被C++标准摒弃,需用unique_ptr替代。