4

私は次のクラスを持っています:

 class list {
      private:
        struct node {
          node() { data=T(); prev=next=this; }
          ˜node() {}
          T data;
          node *prev;
          node *next;
        };
      public:
        class iterator {
        public:
          iterator() : p(NULL) {}
          T & operator*() { return p->data; }
          iterator & operator++()
            { p = p->next; return *this; }
          iterator & operator++(int)
            { iterator tmp = *this; ++*this; return *tmp; }
          bool operator==(const iterator & rhs) const
            { return p == rhs.p; }
          bool operator!=(const iterator & rhs) const
            { return p != rhs.p; }
        private:
          friend class list<T>;
          iterator(node *p) : p(p) {}
          node *p;
        };
        iterator begin() { return iterator(head->next); }
        iterator end() { return iterator(head); }
        list();
        ˜list();
        etc ...
      private:
        int N;
        node *head;
        node *findnode(int);
    };

begin() 関数がイテレータ クラスのコンストラクタを返すことがわかります。これは、呼び出されたときに新しいイテレータが作成されるということですか? もしそうなら、この反復子が割り当てられている変数が範囲外になった後、メモリはリサイクルされますか? イテレータ コンストラクタには戻り値の型がないため、少し混乱しています。誰かが私の問題に光を当てることができれば、私は最も感謝しています.

4

1 に答える 1

9

はい、begin が呼び出されると、新しい反復子が作成されます。大まかに言えば、はい、イテレータが占有するメモリは、範囲外になった後にリサイクルされます。

コンストラクターは、初期化するメモリ上で呼び出されるため、戻り値の型を持ちません。

やや低いレベルでは、スタック上で宣言された変数は、スコープ外に出るときにデストラクタが呼び出されます。これは、「リサイクル」の 1 つの側面です。それらが占有するメモリはヒープではなくスタック上にあるため (new が呼び出された場合と同様)、削除やガベージ コレクションを実行しても解放されません。むしろ、変数が占有していたメモリは、スコープ外になった直後にスタック フレームが削除または追加されるかどうかに応じて、しばらくの間アイドル状態になるか、すぐに上書きされる可能性があります (つまり、関数がスタックに戻っているか、新しい呼び出しが行われています)。 .

于 2012-11-15T22:29:54.430 に答える