注: 從c++11開始, auto_ptr已經被標記為棄用, 常見的替代品為shared_ptr
shared_ptr的不同之處在於引用計數, 在復制(或賦值)時不會像auto_ptr那樣直接轉移所有權
auto_ptr
- auto_ptr實際也是一種類, 擁有自己的析構函數, 生命周期結束時能自動釋放資源
- 正因為能自動釋放資源, 特別適合在單個函數內代替new/delete的調用, 不用自己調用delete也不用擔心意外退出
- auto_ptr對資源的擁有者只能有一個, 當兩個auto_ptr進行等於號(賦值)操作時, 等於號后面的auto_ptr將失去資源的所有權
- 如果只是想顯示auto_ptr對應資源的信息, 而不是更改的話, 要以const auto_ptr&(const + 引用)的方式來傳遞給其它函數
賦值與安全傳遞
#include <iostream>
#include <memory>
using namespace std;
template<class T>
ostream& operator<< (ostream& os,const auto_ptr<T>& p){
if(p.get() == NULL)
os<<"NULL";
else
os<<*p;
return os;
}
int main(int argc,char *argv[]){
auto_ptr<int> p(new int(42));
auto_ptr<int> q;
cout<<"after initialization"<<endl;
cout<<"p:"<<p<<endl;
cout<<"q:"<<q<<endl;
q=p;
cout<<"after assign"<<endl;
cout<<"p:"<<p<<endl;
cout<<"q:"<<q<<endl;
*q += 13;
p=q;
cout<<"another assign"<<endl;
cout<<"p:"<<p<<endl;
cout<<"q:"<<q<<endl;
return 0;
}
非安全傳遞
以下與上面的例子差不多也只是顯示auto_ptr所指對象的值, 以非const 引用的方向傳遞, 結果在函數調用中就把資源給釋放了
#include <iostream>
#include <memory>
using namespace std;
template<class T>
ostream& operator<< (ostream& os,auto_ptr<T> p){
if(p.get() == NULL)
os<<"NULL";
else
os<<*p;
return os;
}
int main(int argc,char *argv[]){
auto_ptr<int> p(new int(42));
cout<<p<<endl;
if(p.get() == NULL)
cout<<"after call function, p = NULL"<<endl;
return 0;
}
shared_ptr
#include <iostream>
#include <tr1/memory>
using namespace std;
class base{
public:
base(){cout<<"base init"<<endl;}
virtual ~base(){cout<<"base over"<<endl;}
virtual void show(){cout<<"from base"<<endl;}
};
class derived: public base{
public:
derived(){cout<<"derived init"<<endl;}
~derived(){cout<<"derived over"<<endl;}
void show(){cout<<"from derived"<<endl;}
};
int main () {
tr1::shared_ptr<derived> ptr(new derived());
tr1::shared_ptr<derived> ptr2(ptr);
cout<<ptr.get()<<endl;
cout<<ptr2.get()<<endl;
class derived *dptr=ptr.get();
dptr->show();
return 0;
}