ステップ 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::auto _ptr< Ty>': コピー コンストラクターが使用できないか、コピー コンストラクターが '明示的に宣言されています' c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0 608
結論は次のとおりです。そのような例をコンパイルすることさえできません。なぜ彼らは私がコンパイルできないことをするのを妨げているのですか?? 彼らの予防策は必ずしも正しいとは限りません。
ステップ2
設計上、要素型auto_ptr
としてvector
直接使用することはできません。auto_ptr
しかし、以下に示す方法で「auto_ptr」をラップすることができます。
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <functional>
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<std::auto_ptr<T> *>(this)) = *(static_cast<std::auto_ptr<T> *>(const_cast<auto_ptr_my *>(&right)));
return *this;
}
auto_ptr_my(const auto_ptr_my<T>& right) {
*this = right;
}
};
namespace std
{
template<> struct 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
。
ステップ 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
でコンテナーを
使用できる場合もあれば、そうでない場合もあります。とにかく悪い習慣です。ただし、STL コンテナーやアルゴリズムで直接使用できないように設計されていることを忘れないでください。これに対して、ラッパー コードを作成する必要があります。最後に、STL コンテナーでの使用は自己責任で行ってください。たとえば、一部の実装では要素の処理中にクラッシュが発生しませんが、他の実装では直接クラッシュが発生します。auto_ptr
auto_ptr
sort
vector
この質問には学術的な目的があります。STEP 3 のクラッシュ例を提供してくれた KennyTM に感謝します。