2011年8月16日 星期二

shared_ptr / unique_ptr vs auto_ptr

shared_ptr與unique_ptr是C++0x中用來取代過去auto_ptr以避免定去的定義曖昧不明所造成的誤用

下面這段code是從The C++ Standard Library的autoptr1.cpp中節錄出來的

int main(void)
{
 auto_ptr p(new int(42));
 auto_ptr q;

 cout << "after initialization: " << endl;
 cout << " p: " << p << endl;
 cout << " q: " << q << endl;

 q = p;
 cout << "after assigning auto pointers: " << endl;
 cout << " p: " << p << endl;
 cout << " q: " << q << endl;

 *q += 13;
 p = q;
 cout << "after change and reassignment: " << endl;
 cout << " p: " << p << endl;
 cout << " q: " << q << endl;

 return 0;
}

執行結果:
after initialization: 
 p: 42
 q: NULL
after assigning auto pointers:
 p: NULL
 q: 42
after change and reassignment:
 p: 55
 q: NULL

 如果改用shared_ptr取代auto_ptr
shared_ptr p(new int(42));
shared_ptr q;
編譯時無錯誤或警告,而執行果結則變成了

after initialization:
 p: 42
 q: NULL
after assigning auto pointers:
 p: 42
 q: 42
after change and reassignment:
 p: 55
 q: 55

使用shared_ptr的物件,當與其他物件共享時,其內部會將其參用計數+1,而auto_ptr則不允許共享,會進行所有權的轉移。 如果改用unique_ptr取代auto_ptr
unique_ptr p(new int(42));
unique_ptr q;
則在編譯時
q = p;  // error C2248: 'std::unique_ptr<_Ty>::operator =' : ...
...
q = p;  // error C2248: 'std::unique_ptr<_Ty>::operator =' : ...
都產生了error C2248的錯誤,使用unique_ptr的物件是不允許物件共享,而為了明確表示物件所有權的轉移,必需使用std::move來轉移所有權。程式需改為:
q = move(p); // q = p;
...
p = move(q); // q = p;

執行結果與auto_ptr相同。