为什么要用智能指针?
我们知道在C++中,资源管理是个头疼的问题。资源管理最常做的就是内存管理。而指针用起来如果忘记归还,就会导致内存泄露。
比如:
class Oneclass{};
int func(){
Oneclass* one=new Oneclass;
if(!one)return 1;
delete one;
return 0;
}
可见,上面代码中,我们可以发现delete并没什么卵用,函数没有执行到delete,而是直接返回了1;最好的办法就是不用指针,使用对象来管理资源,因为对象有析构函数,当函数执行的最后会调用析构函数自动回收资源。
普通指针还可能导致悬垂指针。一个指针复制另一个指针,两个指针所指的是同一个对象,当使用一个指针改变那对象时,另一个指针还傻傻地以为还是原来的对象。
那肿么办呢?难道就不用指针这一神器了吗?
不用怕,还有智能指针这一神器,我们可以自定义一个智能指针,或者使用标准程序库的auto_ptr;如下:
void func(){
std::auto_ptr<Oneclass> pt(new Oneclass);
}
当控制流离开func()的之前会自动调用auto_ptr的析构函数释放对象资源。
但是最好别用多个auto_ptr指向同一个对象,因为如果一个auto_ptr释放了那个对象,其它auto_ptr还傻傻地以为他们对象还活着。而且auto-ptr使用复制或者赋值时有点特别,完成复制或赋值后它们会变成null;比如
void func(){
std::auto_ptr<Oneclass> pt1(new Oneclass);
std::auto_ptr<Oneclass> pt2(pt1); //pt1变成null
std::auto_ptr<Oneclass> pt3=pt2; //pt2变成null
}
如果把指针比作丈夫,对象比作妻子,那auto_ptr就只能是一夫一妻制了;而下面这位就厉害了,tr1::shared_ptr就可以一妻多夫,它有个计数器,计算他的同妻伙伴的个数,当为0时,他们的对象也没有存在的意义了。比如:
void func(){
std::tr1::shared_ptr<Oneclass> pt1(new Oneclass);
std::tr1::shared_ptr<Oneclass> pt2(pt1); //pt1没变化
std::tr1::shared_ptr<Oneclass> pt3=pt2; //pt2没变化
}
虽然auto_ptr和tr1::shared_ptr像是指针,但实质却还是对象,如果函数需要调用一个Oneclass指针的话,那就会出问题,幸运的是它们都提供了一个get成员函数,可以返回原始指针。比如:
void ptuse(const Oneclass* one){};
void func(){
std::tr1::shared_ptr<Oneclass> pt1(new Oneclass);
std::auto_ptr<Oneclass> pt2(new Oneclass);
ptuse(pt1.get());
ptuse(pt2.get());
}
时间: 2024-10-06 15:47:36