2015-02-24 49 views
1

據我所知,auto_ptr不能與矢量一起使用,因爲auto_ptr不符合作爲可複製構造的要求。由於被複制的auto_ptr被修改,因此複製不會導致兩個完全相同的副本,從而違反了可複製構造方式。爲什麼unique_ptr可以用於std容器,vector <>例如?

Unique_ptr也似乎也這樣做;它修改被複制的對象 - 被複制對象的指針成員被設置爲nullptr。 那麼,怎麼可能使用uinque_ptr與矢量而不是auto_ptrs?

我的理解是否正確或我在這裏錯過了什麼?

auto_ptr <int> autoPtr(new int); 
vector < auto_ptr <int> > autoVec; 
autoVec.push_back(autoPtr);   //compiler error..why? 

unique_ptr <int> uniquePtr(new int); 
vector < unique_ptr <int> > uniqueVec; 
uniqueVec.push_back(std::move(uniquePtr)); //okay..why? 
+3

[所以你不能複製它](http://coliru.stacked-crooked.com/a/495f091f798712ab),[但你可以移動它](http://coliru.stacked-crooked.com/ a/361fc294fb13279d) – 2015-02-24 05:01:16

+0

@VxxGxx這只是'auto_ptr'不能提供任何防止被嘗試複製清除的保護。此外,'auto_ptr'已棄用。不過,這至少會給你一個警告。 – 2015-02-24 06:34:03

+0

@BryanChen我們可以拷貝(通過auto_ptr中的非const引用)或者移動它(通過右值引用),被拷貝的對象被改變。這違反了複製構造的習慣用法。那麼是什麼讓unique_ptr適合像vector這樣的容器而不是auto_ptr? – Vishal 2015-02-24 08:18:35

回答

2

auto_ptr的問題在於不希望修改對象的操作確實修改了它。複製構造函數修改了源代碼。

unique_ptr沒有拷貝構造函數。它有一個移動構造函數。移動構造函數也修改源代碼,但這是預期的,並且泛型代碼可以區分使用複製構造函數的情況和使用移動構造函數的情形。

vector(以及其他容器)在寫入後不會神奇地與unique_ptr一起工作。他們必須更新,以便他們可以使用移動類型。這是在C++ 11中完成的。有可能進行此修改,因爲移動和複製是不同的操作。這是不可能的auto_ptr相同,因爲該類有一個奇怪的副本構造函數。

0

編譯錯誤是因爲試圖修改auto_ptr const&正式參數(通過複製它)在push_back實現中。

而不是

autoVec.push_back(autoPtr); 

你可以做

autoVec.emplace_back(autoPtr.release()); 

或者更直接(不使用autoPtr變量)

autoVec.emplace_back(new int(42)); 

然而,儘管這部作品在技術意義上(免責聲明:代碼甚至沒有被任何編譯器瀏覽)你仍然有的問題項目由於嘗試複製而自行歸零。所以這一切都非常非常不安全。此外,auto_ptr已在C++ 11中棄用;我不知道它現在是否完全被刪除,但這不是不可能的。

相關問題