auto ptr智慧型指針

auto ptr智慧型指針是一個計算機中的操作指令

基本介紹

  • 中文名:auto ptr智慧型指針
  • 性質:智慧型指針
  • 內容:它是“它所指向的對象”的擁有者
  • 特點:一個對象只能有一個擁有者
基本信息,特色,

基本信息

auto_ptr指針介紹(智慧型指針)
auto_ptr指針介紹
auto_ptr是這樣一種指針:它是“它所指向的對象”的擁有者。這種擁有具有唯一性,即一個對象只能有一個擁有者,嚴禁一物二主。當auto_ptr指針被摧毀時,它所指向的對象也將被隱式銷毀,即使程式中有異常發生,auto_ptr所指向的對象也將被銷毀。
1、設計動機:
函式中通常要獲得一些資源,執行完動作後,然後釋放所獲得的資源,當程式設計師忘記釋放所申請的到的資源,或者由於異常發生而沒有正常釋放資源時,這就將產生一系列的記憶體泄漏問題。
因此,你可能將函式寫成如下形式:
void fun()
{
try
{
T *ptr = new T;
......
}catch(...)
{
delete ptr;
throw;
}
delete ptr;
}
這樣使程式變得太過複雜。使用auto_ptr可以使上述程式簡化為:
void fun()
{
auto_ptr ptr(new T);
......
}
不再需要delete,也不再需要catch了。與上面的程式相比,這個非常簡單。
auto_ptr是一個模板類,適合於任何類型,其接口行為與普通指針相似,opeator *用來提取其所指向對象的值。operator->用來指向對象中的成員。但是,他沒有定義任何的算術運算(包括++)。
由於auto_ptr定義中“用一般指針構造一個auto_ptr”的構造函式被聲明為explicit(拒絕隱式變換),所以一下的方式是錯誤的:
auto_ptr ptr = new int(0); // 錯
必須這樣:
auto_ptr ptr(new int(0)); //正確
2、auto_ptr擁有權的轉移
由於auto_ptr指針唯一性,即一個對象只能有一個auto_ptr指針所指向它。因此,當auto_ptr以傳值方式被作為參數傳遞給某函式時,這時對象的原來擁有者(實參)就放棄了對象的擁有權,把它轉移到被調用函式中的參數(形參)上,如果函式不再將擁有權傳遞出去,由於形參的作用域僅僅為函式內部,當函式退出時,它所指向的對象將被銷毀。當函式返回一個auto_ptr時,其擁有權又被轉移到了調用端。
因此,應該儘量不要在參數中使用auto_ptr指針,我們也不要通過引用傳遞auto_ptr。
當然一個方法是我們可以通過使用常量引用來實現auto_ptr的傳遞,我們也可以聲明一個const auto_ptr指針,這樣將使auto_ptr不能轉移它的擁有權。
例如:
void print(auto_ptr ptr);
const auto_ptr p(new int(0));
*p = 10;
print(p); //編譯時發生錯誤
auto_ptr被使用最為一個類成員時,由於其可能發生擁有權轉移的問題,所以你必須親自寫複製構造函式和複製運算操作符。
3、auto_ptr的錯誤運用:
1)、auto_ptr之間不能共享一個對象。一個auto_ptr不能指向另一個auto_ptr所指向的的對象。否則,當第一個指針刪除該對象時,林一個指針馬上就指向了一個已經被銷毀的對象,那么,如果在使用該指針,就會引發某些錯誤。
2)、並不存在針對array而設計的auto_ptrauto_ptr不可以指向一個array,因為auto_ptr是通過delete而不是delete[]來釋放其所擁有的資源的。
3)、auto_ptr絕非是一個通用的智慧型指針。並非任何適用智慧型型指針地方都可以適用auto_ptr指針。
4)、auto_ptr不滿足STL容器對其元素的要求。因為在拷貝和賦值動作以後,原本的auto_ptr和新產生的auto_ptr並不相等,在拷貝和賦值之後,原本的auto_ptr會交出擁有權,而不是拷貝給新的auto_ptr。因此,決不要將auto_ptr作為標準容器的元素。

特色

以下附auto_ptr部分原始碼:
template
class auto_ptr
{
private:
T * ptr;
public:
typedef T element_type;
explicit auto_ptr(T* __p = 0) throw() : ptr(__p) {}
auto_ptr(auto_ptr& __a) throw() : ptr(__a.release()) {}
template
auto_ptr(auto_ptr<_Tp1>& __a) throw(): ptr(__a.release()) {}
auto_ptr& operator=(auto_ptr& __a) throw()
{
if (&__a != this)
{
delete ptr;
ptr = __a.release();
}
return *this;
}
template
auto_ptr& operator=(auto_ptr<_Tp1>& __a)throw()
{
if (__a.get() != this->get())
{
delete ptr;
ptr = __a.release();
}
return *this;
}
~auto_ptr() throw() { delete ptr; }
T& operator*() const throw() { return *ptr; }
T* operator->() const throw() { return ptr; }
T* get() const throw() { return ptr; }
T* release() throw()
{
T* __tmp = ptr;
ptr = 0;
return __tmp;
}
void reset(T* __p = 0) throw()
{
delete ptr;
ptr = __p;
}
}

相關詞條

熱門詞條

聯絡我們