3

現在の宿題では、リストのイテレータクラスを作成しています。私は良いerase(iterator where)関数を作成することに固執しています。

現在のコード(質問に合うように縮小):

class List
{
    class _Iter
    {
        friend class List;
    public:
        _Iter(ListElem *pCurr, List *pList);

        /* *, ->, ++, --, == and != operators overloaded */

    private:
        ListElem *pCurr_; List *pList_;
    };

    typedef _Iter iterator;

    iterator erase(iterator where);
};

消去は次のように実装されます。

// Precondition: List has been checked for size > 0.
List::iterator List::erase(List::iterator& where)
{
    // Erasing only element in list.
    if(where == end() && where == begin())
    {
        pop_back(); // or pop_front();
        return iterator(0, this);
    }

    // Elem at end
    if(where == end())
    {
        pop_back();
        return end();
    }
    else 
    {
        // Elem at beginning
        if(where == begin())
        {
            pop_front();
            return ++begin();
        }
    }

    // Elem somewhere between beginning and end.
    iterator temp(where);
    // The node next to pCurr_ should point to the one before pCurr_
    where.pCurr_->next->prev = where.pCurr_->prev;
    // The node before pCurr_ should point to the one after pCurr_
    where.pCurr_->prev->next = where.pCurr_->next;
    // Return the node after pCurr_
    ++temp;
    delete where.pCurr_;
    --size_;
    return temp;
} 

最初の3つのケース(要素のみ、最後の要素、最初の要素)はすべ​​て問題ありません。_Iterうまくコーディングされており、知識やメンバーへのプライベートアクセスはまったく必要ありません。ただし、要素がこれらの位置にない場合は、カプセル化に違反してpCurr_(リストの要素)を直接変更する以外に(一見)選択の余地はありません。

これを回避する方法はありますか?STLリストの中を調べましたが、他のいくつかの関数を使用_Next_Node_(/* stuff */)_Prev_Node_(/* stuff */)ていて、あまり役に立ちませんでした。Google検索では、自分で消去機能を作成する方法ではなく、消去機能の使用方法について役立つ結果が得られます。

質問:pCurr_メンバーを取得せずに、イテレーターが指す要素を消去する方法はありますか?

4

2 に答える 2

3
  1. アンダースコアで始まり、その後に大文字が続く識別子は使用しないでください。これらは、標準ライブラリおよびシステムライター用に予約されています。独自のリストクラスを作成していますが、実際には標準ライブラリを作成していません。

  2. end()は通常、リストの最後を過ぎた1つの要素であり、最後の要素ではありません。(リストの実際の最後のイテレーターを取得するには、l.rbegin()。base()を実行できます)。

  3. 非定数参照ではなく、値でイテレータを渡します。

  4. なぜpCurrの変更にそれほど関心があるのですか?

于 2010-12-20T14:34:34.383 に答える
2

これは実際にはカプセル化に違反していません。コンテナとそのイテレータが緊密に結合されていることはほぼ避けられません。それらの2つは一緒に、ユーザーから実装の詳細を隠します。彼らがお互いに友達でなかったら、より多くの実装の詳細をユーザーに漏らさなければならないでしょう。問題のクラスがお互いの内部について知る正当な理由がある場合、friendキーワードはカプセル化を強化できます。

begin() == end()1つの要素でリストを表すことは、コンテナが空であることを意味する標準ライブラリの規則ではないことに注意してください。end()イテレータをコンテナの「最後から1つ」に戻す必要があります。

于 2010-12-20T14:39:47.110 に答える