- auto_ptr:c++11前就存在於c++庫中:
int main(){
auto_ptr<int> ptr1(new int);
auto_ptr<int> ptr2(ptr1);
//拷貝構造ptr2,ptr1底層的裸指針會被置爲nullptr,ptr1底層裸指針原來的指向賦值給了ptr2的裸指針
return 0;
}
1.auto_ptr拷貝構造函數:
auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
2.拷貝構造函數調用release()方法,轉移裸指針的所有權:
element_type*release() throw()
{
element_type* __tmp = _M_ptr;
_M_ptr = 0;
return __tmp;
}
總結:在涉及到較多賦值和拷貝構造的場景下,不要使用auto_ptr,這個指針很危險。
- scoped_ptr:c++11新增:
#include <boost/scoped_ptr.hpp>
using namespace boost;
int main(){
boost::scoped_ptr<int> ptr1(new int);
//boost::scoped_ptr<int> ptr2(ptr1);//不允許,編譯無法通過
return 0;
}
scoped_ptr的拷貝構造函數和賦值運算符重載函數都被delete:
scoped_ptr(const scoped_ptr<T>&) = delete;
scoped_ptr<T>& operator=(const scoped_ptr<T>&) = delete;
總結:scoped_ptr從引用一個資源開始,從一而終,不能用來拷貝構造不能賦值。
- unique_ptr:c++11新增:
unique_ptr的拷貝構造函數和賦值運算符重載函數都被delete:
unique_ptr(const unique_ptr<T>&) = delete;
unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;
不同的是,unique_ptr提供了帶右值參數的拷貝構造函數和賦值運算符重載函數:
int main(){
unique_ptr<int> ptr1(new int);
//unique_ptr<int> ptr2(ptr1);無法調用unique_ptr帶左值參數的拷貝構造
unique_ptr<int> ptr2(std::move(ptr1));//調用unique_ptr帶右值參數的拷貝構造函數
return 0;
}
這裏是ptr1把自己的資源都移交給了ptr2,所以,ptr1中的資源我們就不能再去訪問了,
總結:我們顯示的使用帶右值引用的拷貝構造和賦值運算符重載,其實也是在提醒我們開發者,既然拷貝構造新對象了,原來的資源就不要去訪問了,因爲指針指向的資源已經被轉移到新對象上了,即ptr1 --> ptr2.
如果需要使用不帶引用計數的智能指針,推薦使用unique_ptr,這樣更安全,更高效。