auto_ptr 不可被共享,只能指向一个对象
auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:
int* p = new int(0);
auto_ptr<int> ap(p);
从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。
这里我们有几点要注意:
1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:
int* p = new int(0);
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p);
因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr.
2) 考虑下面这种用法:
int* pa = new int[10];
auto_ptr<int> ap(pa);
因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。
3) 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。
4) 因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:
~auto_ptr() throw()
{
if(ap) delete ap;
}
// STL.cpp : 定义控制台应用程序的入口点。 // //智能指针在其生命周期结束后会自动调用delete #include "stdafx.h" #include<iostream> #include<memory> using namespace std; class WebSite { public: WebSite(int x){i = x;cout << i << "调用构造函数" << endl;} ~WebSite(){cout << "调用析构函数" << endl;} void output(){cout << "output" << endl;} private: int i; }; int _tmain(int argc, _TCHAR* argv[]) { auto_ptr<WebSite> autop1(new WebSite(4));//定义了一个WebSite类的指针autop1 auto_ptr<WebSite> autop2(new WebSite(7)); autop1->output(); cout << autop1.get() << endl; //得到auto的一个指针 cout << autop2.get() << endl; //autop1.reset(); //将auto指向NULL //cout << autop1.get() << endl; ////autop1->output(); //reset之后auto不可以再使用了 autop1 = autop2; //析构原来autop1指向的地址,将autop2指向的之地址赋给autop1。 //也就是说智能指针只能对一个对象并保持该地址 cout << autop1.get() << endl; cout << autop2.get() << endl; return 0; }
shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷。