Przeciążanie operatora inkrementacji dla iteratora listy

0

Witam,

mam problem z implementacją przeciążenia operatora inkrementacji dla iteratora będącego wskaźnikiem do poszczególnych elementów listy. Chodzi o to, że napisałem klasę Lista na wzór szablonu list z stl. U mnie wygląda to mniej więcej tak:

class Lista
{
private:
	struct Node{
		int dana;
		struct Node * next;
	};

	Node * head; //wskaźnik to pierwszego elementu
	Node * tail; //wskaźnik do ostatniego

public:
        typedef Node* iterator;
	iterator op_Increment(iterator &it)//no właśnie wiem, że to jest źle, tylko nie znam sposobu na przekazanie iteratora do funkcji
	{
		
		it=it->next;
		return it;
	}
}

No i gdzies w main() wypisywanie wartości listy:

Lista lst;
Lista::iterator it = lst.begint();
while(it != NULL)
{
	cout << it->dana << endl;
	++it; //ładnie wygląda
}

Byłbym wdzięczny za jakieś sugestie jak to lepiej zrobić.

0

wydaje mi sie ze iterator nie jest wskaznikiem do node. ja bym zrobil cos takiego bardziej

class iterator
{
public:
  void operator++() { increment(); };    //++a;
  void operator++(int) { increment(); }; //a++;
  void increment() { /* to zastap swoim kodem */ if(it->next) it=it->next; }
private:
  Node* begin;
  Node* end;
  Node* it;
};
0

Sposób wydaje się dobry, bo wczoraj próbowałem zastosować ten pomysł, ale coś mi nie wychodziło.
W Twojej klasie brakuje chyba konstruktora, i nie wiem czy funkcja przeciążenia operatora nie powinna zwracać wartości. Ja zrobiłem coś takiego ale nie działa:

class iterator{
	public:
		iterator(Node * pos) { it=pos;}
		iterator operator++(){ it=it->next; return *this;}
	private:
		Node * it;
	};

Node * Lista::begin(){return head;}
i w main():

Lista::iterator it = lst.begin();//wskaxnik na pierwsze element
cout << it->dana;

Niestety to nie działa, wyskakują jakieś błędy czyli ewidentnie jest gdzieś błąd..

0
class Lista
{
private:
        struct Node{
                int dana;
                struct Node * next;
        };

        Node * head; //wskaźnik to pierwszego elementu
        Node * tail; //wskaźnik do ostatniego

public:
        class iterator {
               Lista *toList;
               Node *toNode;
         private:
               iterator(Lista *list, Node *node) toList(list), toNode(node){
               }

         public:
               // domyślny copy konstruktor jest ok

               iterator() toList(NULL), toNode(NULL){
               }
             
               iterator &opertor=(const iterator& other) {
                    toList = other.toList ;
                    toNode = other.toNode;
                    return *this;
               }

               // operator preinkrementacji
               iterator& operator++() {
                    if(toList && toNode)  {
                         toNode = toNode->next;
                    }
                    return *this;
               }

               // operator postinkrementacji
               iterator operator++(int) {
                    iterator orginal(*this);
                    ++*this;
                    return orginal;
               }

               operator(bool)() const {
                     return toList && toNode;
               }

               int& operator*() {
                     if(toList && toNode)  {
                         return toNode->dana;
                    }
                    assert(0);
                    return (*(int*)NULL);
               }
        };

        iterator begin() {
             return iterator(this, head);
        }
}
0

Niestety pojawia mi się błąd kompilacji:

\(71) : error C2544: expected ')' for operator '()'
\(71) : error C2144: syntax error : 'bool' should be preceded by ';'
\(71) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
\(71) : error C2059: syntax error : ')'
\(71) : error C2059: syntax error : ')'
\(71) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body

w linijce:
operator(bool)() const

Trudno mi to poprawić bo nigdy nie przeciążałem tego operatora i nie bardzo wiem do czego służy. Próbowałem go zakomentować i coś działać dalej ale pojawiły się błędy w main(): nie przeciążony operator != (przy próbie porównania Lista::iterator it z NULL oraz nie przeciążony operator -> przy próbie cout << it->dana;

0

Wywal nawiasy, operatory konwersji nie mają typu konwertowanego w nawiasach. Wypadałoby też spojrzeć na bibliotekę standardową C++ - tam nie używa się konwersji do bool lecz do void *, co pozwala pewnych pułapek w języku uniknąć.

0

Ok. Wywalenie nawiasów pomogło. Próbuję wyświetlić listę w taki sposób:

Lista::iterator it = lst.begin();
	while (it != NULL){cout << it->dana << endl; ++it;}

I mam problem z nieprzeciążonym operatorem '->':
error C2819: type 'Lista::iterator' does not have an overloaded member 'operator ->'
Czy jest w ogóle możliwe użycie iteratora w taki sposób dla tak napisanej klasy?

0

ale iterator udaje, że ma wskazywać na daną a nie na Node! Node ma być zupełnie niewidzialne dla użytkownika klasy

0

Nie wiem czy dobrze wyraziłem to o co mi chodziło.
Chodziło mi o stworzenie iteratora takiego jak w STL List, który tak samo by się tworzyło i tak samo używało. W poście wyżej napisałem fragment kodu wyświetlający listę i pokazujący jak chcę używać iteratora. Początkowo problemem było przeciążenie operatora inkrementacji, ale teraz problem okazuje się bardziej złożony.

0

No właśnie! iteratory w STL nie udają wskazywania na jakaś wewnętrzną strukturę listy, ale na to co zawiera ta lista. Całe bebechy listy masz schowane, bo nie są do niczego potrzebne na zewnątrz klasy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1