很多人聽說過標準auto_ptr智能指針機制,但并不是每個人都天天使用它。這真是個遺憾,因為auto_ptr優雅地解決了C++設計和編碼中常見的問題,正確地使用它可以生成健壯的代碼。本文闡述了如何正確運用auto_ptr來讓你的代碼更加安全——以及如何避免對auto_ptr危險但常見的誤用,這些誤用會引發間斷性發作、難以診斷的bug。
為什么稱它為“自動”指針?
      auto_ptr只是眾多可能的智能指針之一。許多商業庫提供了更復雜的智能指針,用途廣泛而令人驚異,從管理引用的數量到提供先進的代理服務。可以把標準C++ auto_ptr看作智能指針的Ford Escort(elmar注:可能指福特的一種適合家居的車型):一個簡易、通用的智能指針,它不包含所有的小技巧,不像專用的或高性能的智能指針那么奢華,但是它可以很好的完成許多普遍的工作,它很適合日常性的使用。
      auto_ptr所做的事情,就是動態分配對象以及當對象不再需要時自動執行清理。這里是一個簡單的代碼示例,沒有使用auto_ptr所以不安全:
// 示例 1(a): 原始代碼
//
void f()
{
T* pt( new T );

/*...更多的代碼...*/

delete pt;

      我們大多數人每天寫類似的代碼。如果f()函數只有三行并且不會有任何意外,這么做可能挺好的。但是如果f()從不執行delete語句,或者是由于過早的返回,或者是由于執行函數體時拋出了異常,那么這個被分配的對象就沒有被刪除,從而我們產生了一個經典的內存泄漏。
      能讓示例1(a)安全的簡單辦法是把指針封裝在一個“智能的”類似于指針的對象里,這個對象擁有這個指針并且能在析構時自動刪除這個指針所指的對象。因為這個智能指針可以簡單的當成一個自動的對象(這就是說,它出了作用域時會自動毀滅),所以很自然的把它稱之為“智能”指針:

// 示例 1(b): 安全代碼, 使用了auto_ptr
//
void f()
{
auto_ptr<T> pt( new T );

/*...更多的代碼...*/

} // 酷: 當pt出了作用域時析構函數被調用,
// 從而對象被自動刪除
      
      現在代碼不會泄漏T類型的對象,不管這個函數是正常退出還是拋出了異常,因為pt的析構函數總是會在出棧時被調用。清理會自動進行。
最后,使用一個auto_ptr就像使用一個內建的指針一樣容易,而且如果想要“撤銷”資源,重新采用手動的所有權,我們只要調用release():

// 示例 2: 使用一個 auto_ptr
//
void g()
{
T* pt1 = new T;
// 現在,我們有了一個分配好的對象

// 將所有權傳給了一個auto_ptr對象
auto_ptr<T> pt2( pt1 );

// 使用auto_ptr就像我們以前使用簡單指針一樣
*pt2 = 12; // 就像 "*pt1 = 12;"
pt2->SomeFunc(); // 就像 "pt1->SomeFunc();"

// 用get()來獲得指針的值
assert( pt1 == pt2.get() );

// 用release()來撤銷所有權
T* pt3 = pt2.release();

// 自己刪除這個對象,因為現在
// 沒有任何auto_ptr擁有這個對象
delete pt3;

} // pt2不再擁有任何指針,所以不要
// 試圖刪除它...ok,不要重復刪除 

      最后,我們可以使用auto_ptr的reset()函數來重置auto_ptr使之擁有另一個對象。如果這個auto_ptr已經擁有了一個對象,那么,它會先刪除已經擁有的對象,因此調用reset()就如同銷毀這個auto_ptr,然后新建一個并擁有一個新對象:

// 示例 3: 使用reset()
//
void h()
{
auto_ptr<T> pt( new T(1) );

pt.reset( new T(2) );
// 刪除由"new T(1)"分配出來的第一個T

} // 最后,pt出了作用域,
// 第二個T也被刪除了



PS:再貼一個
http://cns_tech.blogbus.com/logs/4628846.html
#include
#include
#include
using namespace std;

int main(int argc, char* argv[])
{
 auto_ptr api ,api2;
 
 api  = auto_ptr( new int(10) );
 cout<<"api:"<<*api<<endl;
 /*
 api對象的布局:
 一個int數表示該對象是否有效。(==1有效,==0無效)
 一個指針 指向int數據(因為你在聲明api時已經說了它時指向int的)
 */
 api2 = api; //傳遞性:執行完本句之后,api無效,同時api2有效,api2的另一個字段指向int
 auto_ptr aps1,aps2;
 aps1 = auto_ptr(new string("pig") );
 cout<<"aps1:"<<*aps1<
 return 0;

      vc6的說明:auto_ptr
template class auto_ptr
{
public:
    typedef T element_type;
    explicit auto_ptr(T *p = 0) throw();
    auto_ptr(const auto_ptr& rhs) throw();
    auto_ptr& operator=(auto_ptr& rhs) throw();
    ~auto_ptr();
    T& operator*() const throw();
    T *operator->() const throw();
    T *get() const throw();
    T *release() const throw();
};
      The class describes an object that stores a pointer to an allocated object of type T. The stored pointer must either be null or designate an object allocated by a new expression. The object also stores an ownership indicator. An object constructed with a non-null pointer owns the pointer. It transfers ownership if its stored value is assigned to another object. The destructor for auto_ptr deletes the allocated object if it owns it. Hence, an object of class auto_ptr ensures that an allocated object is automatically deleted when control leaves a block, even via a thrown exception.
//好了,估計說了這么多 ,應該知道 auto_ptr的功能和不足了。
//再看看以下我轉過來的文章
      STL中的auto_ptr指針是為了解決內存泄漏問題而設計的。它嚴格限制了指針擁有對指向對象的所有權。auto_ptr指針和普通指針的差別在于對指向對象所有權的處理不同。auto_ptr指針是“傳遞”所有權,而普通指針是“共享”所有權。看下面例子:
std::auto_ptr p1(new int(24));
std::auto_ptr p2;
int *q1 = new int(12);
int *q2;
p2 = p1;
q2 = q1;
      經過兩次賦值后,對于auto_ptr,p1為NULL,*p2為24;對于普通指針,*p1, *p2均為12。第一次賦值,p1把指向對象的所有權傳遞給了p2, p1不再擁有指向對象的所有權。而第二次賦值,q2和q1共享了對同一對象的所有權。因此,對于auto_ptr,一個對象只可能被一個智能指針指向,這樣可有效避免內存泄漏問題。但是同時會引起新問題。看下面例子:
template
void BadPrint(std::auto_ptr p)
{
    if (p.get() == NULL)
    {
         std::cout<
    }
    else
    {
         std::cout<<*p;
    }
}
然后我如下使用BadPrint函數:
std::auto_ptr q(new int(18));
BadPrint(q);
*q = 12;
      該程序并未像我們所期望的一樣:*q的值為12,而是會出現runtime error,why?因為我們把q作為函數參數傳給了BadPrint,因此傳遞完成后q不再擁有對指向對象的所有權,而函數內部的局部變量p會接管q所指向對象的所有權,當函數執行完畢退出時,p的生命期截止同時delete所指向對象。因此q實際變為NULL,所以出錯。如何避免出錯?使用auto_ptr的引用?即 void BadPrint(std::auto_ptr &p)。這是相當糟糕的一種做法。對智能指針使用引用混淆了所有權的問題。它導致所有權有可能被傳遞了,也可能沒有被傳遞。無論如何應當避免對auto_ptr使用引用。
      可見智能指針并非對任何情況都智能。使用auto_ptr要知道:
1. 智能指針不能共享指向對象的所有權
2. 智能指針不能指向數組。因為其實現中調用的是delete而非delete[]
3. 智能指針不是萬能的
4. 智能指針不能作為容器類的元素。
例如:
template
void container::insert(const T &value)
{
   ..........
   X = value;
   ..........
}
      事實上在stl中,所有的container要內部拷貝所傳參數的值時都是傳的const類型的值。因此無法用auto_ptr傳進去。
      假定有一個動態分配的int空間,則在一個時刻只能有一個auto_ptr指針指向他!這就是所有權的獨占性。