Efficitive STLでauto_についてptrのいくつかの説明----原則8--auto_は永遠に創立しませんptrの容器
3557 ワード
率直に言って、本条項は『Effective STL』に登場する必要はありません.auto_ptrの容器(COAPs)は禁止です.それらを使用しようとするコードはコンパイルできません.C++標準委員会はこのような状況を手配するために無数の努力を費やした.
[1].私はもともとCOAPsに関するものを言う必要はありません.あなたのコンパイラはこのような容器に文句を言うべきで、すべてのものはコンパイルできませんから.
ああ、多くのプログラマーはSTLプラットフォームを使ってCOAPsを拒否しません.さらに悪いことに、多くのプログラマーは、COAPsをポインタコンテナ(条項7および33を参照)に伴うリソース漏洩を常に単純かつ直接的かつ効率的に解決する案と見なすことを妄想している.その結果,多くのプログラマーがCOAPsを使用するように誘導され,それらを確立しても成功すべきではない.
私はすぐにCOAPsの幽霊がどれだけ心配されているかを説明して、標準化委員会は特殊な措置を取ってそれらが合法ではないことを保証します.今、autoを必要としないことに集中します.ptrはさらに容器知識の欠点:COAPsは移植できない.どうなるの?C++標準は彼らを禁止し、比較的良いSTLプラットフォームはすでに実現した.時間が経つにつれて、現在標準を実現できないこの態様のSTLプラットフォームがより適応し、それが発生すると、COAPsを使用するコードは現在よりも移植できないと推定するのに十分な理由がある.移植性を重視する場合(そしてあなたは)、移植テストに失敗しただけでCOAPsを拒否します.
しかし、移植的な考えはないかもしれません.もしそうならauto_のコピーを注意させていただきますptrの独特さ--ある人は奇異だと言っている--の定義.
auto_をコピーするとptr時、auto_ptrが指すオブジェクトの所有権はコピーされたauto_に移されるptr、コピーされたauto_ptrはNULLに設定されます.正確に言ってください:autoをコピーします.ptrはその値を変更します.
これは非常に普通ではありません.面白いかもしれませんが、STLのユーザーとして関心を持っているのは、驚くべき行為を招いたからです.たとえば、この正しいコードを考慮すると、auto_が作成されます.ptrのvectorは、次に、指向するWidgetの値を比較する関数を使用してソートされます.
ここのすべてのものは合理的に見え、概念的にはすべてのものが合理的だが、結果は全く合理的ではない.たとえば、ソート中にwidgetsの1つ以上のauto_ptrはNULLに設定されている可能性があります.このvectorをソートする動作は、その内容を変更した可能性があります!これがどのように起こったのかを知る価値がある.
これはsortを実現する方法である一般的な方法であり、それが示すように、高速ソートアルゴリズムを用いた何らかの変形であるからである.クイックソートの利点には関心がありませんが、コンテナをソートする基本的な考え方は、コンテナの要素を「マスター」として選択し、マスターの値以上またはそれ以下の値を再帰的にソートすることです.sort内部では、このような方法が多少少ないように見えます.
STLソースコードを読むのに経験がある限り、これは面倒に見えるかもしれませんが、悪くはありません.唯一の難点はiteratorを引用することです.traits::value_typeは、sortの反復器が指すオブジェクトタイプに伝わる奇妙なSTL方式にすぎない.(iterator_traits::value_typeについては、テンプレートパラメータタイプに依存する名前で、ここではRandomAccessIteratorです.typenameの使い方に関する詳細は、7ページに戻ります.)
上のコードで厄介なのはこの行です.
保存された区間からローカル一時オブジェクトに要素をコピーするためです.私たちの例では、この要素はautoです.ptrなので、このコピー操作は黙ってコピーされたauto_をptr——vectorの中のそれ——NULLに設定します.また、pivotValueが生存期間を過ぎると、指向するWidgetが自動的に削除されます.このときsort呼び出しが返され、vectorの内容が変更され、少なくとも1つのWidgetが削除されました.いくつかのvector要素がNULLに設定されており、いくつかのwidgetが削除されている可能性もあります.高速ソートは再帰アルゴリズムであり、再帰の各層が1つのメタをコピーします.
これは嫌な罠に落ちています.これも、標準委員会がそんなに努力して落ちないようにしている理由です.auto_を確立しないことでptrの容器はあなたの利益に対する仕事を尊重して、たとえあなたのSTLプラットフォームがそれを許可しても.
[1].私はもともとCOAPsに関するものを言う必要はありません.あなたのコンパイラはこのような容器に文句を言うべきで、すべてのものはコンパイルできませんから.
ああ、多くのプログラマーはSTLプラットフォームを使ってCOAPsを拒否しません.さらに悪いことに、多くのプログラマーは、COAPsをポインタコンテナ(条項7および33を参照)に伴うリソース漏洩を常に単純かつ直接的かつ効率的に解決する案と見なすことを妄想している.その結果,多くのプログラマーがCOAPsを使用するように誘導され,それらを確立しても成功すべきではない.
私はすぐにCOAPsの幽霊がどれだけ心配されているかを説明して、標準化委員会は特殊な措置を取ってそれらが合法ではないことを保証します.今、autoを必要としないことに集中します.ptrはさらに容器知識の欠点:COAPsは移植できない.どうなるの?C++標準は彼らを禁止し、比較的良いSTLプラットフォームはすでに実現した.時間が経つにつれて、現在標準を実現できないこの態様のSTLプラットフォームがより適応し、それが発生すると、COAPsを使用するコードは現在よりも移植できないと推定するのに十分な理由がある.移植性を重視する場合(そしてあなたは)、移植テストに失敗しただけでCOAPsを拒否します.
しかし、移植的な考えはないかもしれません.もしそうならauto_のコピーを注意させていただきますptrの独特さ--ある人は奇異だと言っている--の定義.
auto_をコピーするとptr時、auto_ptrが指すオブジェクトの所有権はコピーされたauto_に移されるptr、コピーされたauto_ptrはNULLに設定されます.正確に言ってください:autoをコピーします.ptrはその値を変更します.
auto_ptr<Widget> pw1(new Widget); // pw1 Widget
auto_ptr<Widget> pw2(pw1); // pw2 pw1 Widget;
// pw1 NULL。(Widget
// pw1 pw2。)
pw1 = pw2; // pw1 Widget;
// pw2 NULL
これは非常に普通ではありません.面白いかもしれませんが、STLのユーザーとして関心を持っているのは、驚くべき行為を招いたからです.たとえば、この正しいコードを考慮すると、auto_が作成されます.ptr
bool widgetAPCompare(const auto_ptr<Widget>& lhs,
const auto_ptr<Widget>& rhs) {
return *lhs < *rhs; // , Widget
} // operator<
vector<auto_ptr<Widget> > widgets; // vector,
// Widget auto_ptr ;
// !
sort(widgets.begin(), widgets.end(), // vector
widgetAPCompare);
ここのすべてのものは合理的に見え、概念的にはすべてのものが合理的だが、結果は全く合理的ではない.たとえば、ソート中にwidgetsの1つ以上のauto_ptrはNULLに設定されている可能性があります.このvectorをソートする動作は、その内容を変更した可能性があります!これがどのように起こったのかを知る価値がある.
これはsortを実現する方法である一般的な方法であり、それが示すように、高速ソートアルゴリズムを用いた何らかの変形であるからである.クイックソートの利点には関心がありませんが、コンテナをソートする基本的な考え方は、コンテナの要素を「マスター」として選択し、マスターの値以上またはそれ以下の値を再帰的にソートすることです.sort内部では、このような方法が多少少ないように見えます.
template<class RandomAccessIterator, // sort
class Compare> //
void sort(RandomAccessIterator first,
RandomAccessIterator last,
Compare comp)
{
// typedef
typedef typename iterator_traits<RandomAccessIterator>::value_type
ElementType;
RandomAccessIterator i;
... // i
ElementType pivotValue(*); //
// ;
//
... //
}
STLソースコードを読むのに経験がある限り、これは面倒に見えるかもしれませんが、悪くはありません.唯一の難点はiteratorを引用することです.traits
上のコードで厄介なのはこの行です.
ElementType pivotValue(*i);
保存された区間からローカル一時オブジェクトに要素をコピーするためです.私たちの例では、この要素はautoです.ptr
これは嫌な罠に落ちています.これも、標準委員会がそんなに努力して落ちないようにしている理由です.auto_を確立しないことでptrの容器はあなたの利益に対する仕事を尊重して、たとえあなたのSTLプラットフォームがそれを許可しても.