STEP 1 讓解決一條筆直的路這個問題:
#include <iostream>
#include <vector>
#include <algorithm>
template<> struct std::less<std::auto_ptr<int>>: public std::binary_function<std::auto_ptr<int>, std::auto_ptr<int>, bool> {
bool operator()(const std::auto_ptr<int>& _Left, const std::auto_ptr<int>& _Right) const
{ // apply operator< to operands
return *_Left < *_Right;
}
};
int wmain() {
using namespace std;
auto_ptr<int> apai(new int(1)), apai2(new int(2)), apai3(new int(3));
vector<auto_ptr<int>> vec;
vec.push_back(apai3);
vec.push_back(apai);
vec.push_back(apai2);
for (vector<auto_ptr<int>>::const_iterator i(vec.cbegin()) ; i != vec.cend() ; ++i)
wcout << i->get() << L'\t';
vector<int> vec2;
vec2.push_back(3);
vec2.push_back(2);
vec2.push_back(5);
sort(vec2.begin(), vec2.end(), less<int>());
sort(vec.begin(), vec.end(), less<auto_ptr<int>>());
return 0;
}
在MSVCPP11錯誤文本如下: _ 錯誤1個錯誤C2558:類「的std ::自動 _ptr < Ty>':沒有拷貝構造函數可用或拷貝構造函數被聲明爲'explicit'c:\ program files(x86)\ microsoft visual studio 11.0 \ vc \ include \ xmemory0 608
結論是:我甚至不能編譯這樣的例子。爲什麼他們阻止我做一些我無法編譯的東西?他們的預防並不總是如此。
STEP 2
我們不能用auto_ptr
作爲vector
元素類型直接由於auto_ptr
設計。但是我們可以按照下面介紹的方式封裝`auto_ptr'。
#include <iostream>
#include <vector>
#include <algorithm>
template<typename T> class auto_ptr_my: public std::auto_ptr<T> {
public:
explicit auto_ptr_my(T *ptr = 0) {
this->reset(ptr);
}
auto_ptr_my<T> &operator=(const auto_ptr_my<T> &right) {
*(static_cast<auto_ptr<T> *>(this)) = *(static_cast<auto_ptr<T> *>(const_cast<auto_ptr_my *>(&right)));
return *this;
}
auto_ptr_my(const auto_ptr_my<T>& right) {
*this = right;
}
};
template<> struct std::less<auto_ptr_my<int>>: public std::binary_function<auto_ptr_my<int>, auto_ptr_my<int>, bool> {
bool operator()(const auto_ptr_my<int>& _Left, const auto_ptr_my<int>& _Right) const
{ // apply operator< to operands
return *_Left < *_Right;
}
};
int wmain() {
using namespace std;
auto_ptr_my<int> apai(new int(1)), apai2(new int(2)), apai3(new int(3));
vector<auto_ptr_my<int>> vec;
vec.push_back(apai3);
vec.push_back(apai);
vec.push_back(apai2);
for (vector<auto_ptr_my<int>>::const_iterator i(vec.cbegin()) ; i != vec.cend() ; ++i)
wcout << **i << L'\t';
sort(vec.begin(), vec.end(), less<auto_ptr_my<int>>());
for (vector<auto_ptr_my<int>>::const_iterator i(vec.cbegin()) ; i != vec.cend() ; ++i)
wcout << **i << L'\t';
return 0;
}
此代碼以及表示auto_ptr
可以使用具有vector
和sort
無內存泄漏和崩潰。
STEP 3 作爲KennyTM貼在下面:
前return 0;
語句添加以下代碼:
std::vector<auto_ptr_my<int>> vec2 = vec;
for (vector<auto_ptr_my<int>>::const_iterator i(vec2.cbegin()) ; i != vec2.cend() ; ++i)
wcout << **i << L'\t';
wcout << std::endl;
for (vector<auto_ptr_my<int>>::const_iterator i(vec.cbegin()) ; i != vec.cend() ; ++i)
wcout << **i << L'\t';
wcout << std::endl;
...和得到內存泄漏!
結論 有時候,我們可以使用auto_ptr
與容器不可見的崩潰,有時沒有。無論如何,這是不好的做法。 但是不要忘記auto_ptr
的設計方式使得你不能直接使用STL容器和算法:反對你必須編寫一些包裝代碼。最後使用auto_ptr
與STL容器是您自己的風險。例如,某些sort
的實現不會在處理vector
元素時導致崩潰,但其他實現將直接導致崩潰。
這個問題有學術目的。 感謝KennyTM提供的STEP 3崩潰示例!
我相信你不需要再關注這個了,因爲'auto_ptr **作爲一個整體**現在已經被棄用了。改爲使用'unique_ptr',你也可以把它放在容器中。 – Kos 2011-12-25 17:06:32
@Kos我也讀過新標準。請回答我的問題。停止貼出主題的帖子。 – DaddyM 2011-12-25 17:08:19
@DaddyM好吧,它是關於主題的。 – 2011-12-25 17:18:49