Czy na tej zasadzie działa iterator

0

bawię się kodem i wymyślam różne rzeczy to jest kod z tylnej części ciała - bo chcę coś zrozumieć - zrobiłem tablicę na adresy określonego typu danych - chciałbym zapytać czy mniej więcej na tej zasadzie działa iterator ?
Albo inne pytanie - jaką strukturę danych pętla for może wam przypominać ? Lista już była

class Test1
{
public:
    Test1(){
        licznik++;
    }

    void addressOfObject(Test1 &ptr){
        this->ptr = &ptr;

        cout << "object adress is " << this->ptr << endl;
    }

    void nextObj(){
        cout << ptr++ << endl;
    }

    int sumOfObjects(){
        return licznik;
    }

private:
    static int licznik;
    /*static */Test1 *ptr;
};

int Test1::licznik = 0;
//Test1 *Test1::ptr = nullptr;

int main()
{
    Test1 *t1 = new Test1;
    t1->addressOfObject(*t1);

    Test1 *t1a = new Test1;
    t1a->addressOfObject(*t1a);

    Test1 *t1b = new Test1;
    t1b->addressOfObject(*t1b);

    Test1 *tab[]={t1,t1a,t1b};

    for(int i=0; i<t1->sumOfObjects(); ++i){
        tab[i]->nextObj();
    }

    return 0;
}
3

Zlituj się.

ten kod jest tak dalece do niczego niepodobny, zamysł klasy nie tylko że nie przypomina NICZEGO co w programowaiu obiektowym ma miejsce, ale właściwie trudny do odgadnięcia zamiar autora, nawet obniżajac wymogi na "nieudolny poziom"

I tu nie ma nawet ani jednej literki z iteratora C++, NIC.

Jakie w zasadzie jest pytanie, i jakiej odpowiedzi się spodziewasz ?
Na iterator nie ma miejsca, aby nawet w zarysie rozmawiać, bez podstaw (kontenery, itd)

3

Naprawdę fundameny, potem użycie "gotowego" iteratora, wielokrotnie, różnych kontekstach - potem zastanawianie się co ma we flakach..

Konkretnie iteratror to taka abstrakcja, która wyznacza kolejny Z KOLEKCJI (gdzie tu masz jakakolwiek, choćby szkolną, kolekcję?!?!) - i to powinno na początek wystarczyć.

Implementacja np w Javie, C# jest może nie długa, ale zaawasowana w swoim zamyśle obiektowym, w C# chyba korzysta z zaawansowanych ficzerów języka

W C++ jeszcze trudniejsza, bo przez template. Może niewiele kodu, ale jazda bez trzymanki

0
ZrobieDobrze napisał(a):

I tu nie ma nawet ani jednej literki z iteratopra C++, NIC.

WIEM - tyle, że mi chodziło o to, chciałem się dowiedzieć czy iterator gdzieś na boku ma taką tablicę adresów i się do nich odwołuje iterując po obiektach ?
Bo wyobraziłem sobie sytuację, że mam gdzieś w kodzie powiedzmy 10 obiektów jakiegoś typu i chciałbym znaleźć je wszystkie

1
zkubinski napisał(a):
ZrobieDobrze napisał(a):

I tu nie ma nawet ani jednej literki z iteratopra C++, NIC.

WIEM - tyle, że mi chodziło o to, chciałem się dowiedzieć czy iterator gdzieś na boku ma taką tablicę adresów i się do nich odwołuje iterując po obiektach ?
Bo wyobraziłem sobie sytuację, że mam gdzieś w kodzie powiedzmy 10 obiektów jakiegoś typu i chciałbym znaleźć je wszystkie

Sa udowodniłeś, że nie masz nawet pobieżnego "użytkowego" wyczucia, co to jest iterator. Gdybyś choć trochę rósł w umiejetnosciach krok za krokiem, jak każdy z nas rósł, najpierw byś go dłużej używał jako użytkownik, a o wiele póżniej (albo wcale) zastanawiał sie co ma pod maską.

Iterator, w każdym z języków - nie jest bytem samodzielnym, ale pewnego rodzaju... akcesorem (znów pewnie podaję słowo, które ci zaszkodzi) do kolekcji. Nie ma mowy o istnieniu iteratora bez "jakiejś" kolekcji

Masz braki w takim bazowym przedmiocie "struktury danych i algorytmy" - o czym odpowiadałem na priv - nie da sie tego przeskoczyć "bo bardzo chcę i będę zgadywał"

EOT, wątek nie ma sensu.

2

Coś ci dzwoni, nie wiesz w którym kościele. Zasadniczo, jeśli zastanawiam się „co podmiot liryczny miał na myśli”, mniej więcej coś w ten deseń, pod warunkiem, że iterujemy po tablicy w pamięci. Natomiast idea iteratora polega na tym, żeby stworzyć jednolity interfejs dla przeglądania kolejnych elementów tablicy, co drugiego elementu, kolejnych linijek z pliku, kolejnych rządań HTTP, czegokolwiek. Dlatego w zależnośći od przypadku te implementacje będą się różnić. Oczywiście kod jest niepoprawny, nie będę się rozwodzić, ale najbardziej rażący błąd to to, że pole licznik jest static i do tego jeszcze inicjalizowane gdzieś poza klasą. Taki licznik może, ale wcale nie musi istnieć. Dla tablicy (przez wskaźnik) musi być podany w konstruktorze, dla wektoru będzie odczytany z objektu, ale dla strumienia nie jesteśmy w stanie określić ilości elementów z góry i w ogóle go nie będzie… Poza tym iterator powinien sam rozpoznawać sytuację gdy doszedł do końca przeglądanego zbioru i w jakiś sposób to sygnalizować. Też metoda nextObj powinna zwracać wartość, a nie wypisywać ją przez cout.

6

po raz kolejny "nie wiem jak dziła iterator, moze na 4p wiedzą?"
Człowieku każdy zadawał sobie takie pytanie i jest milion odpowiedzi z przykładami np.
https://www.internalpointers.com/post/writing-custom-iterators-modern-cpp
(chociaż lepiej przeglądąnąć więcej źródeł niż to konkretne, to tylko przykład że wszystko jest na wyciągnięcie ręki)

powiem to co wiele razy mówiłem tobie się niechce uczyć tylko chcesz menotrigu za darmo.

3

Ogólnie masz dosyć słabą umiejętność wyszukiwania informacji, dam ci przykład jak powinno się zdobywać wiedzę.

Na sam początek powinieneś nauczyć się używać iteratora, bo jest najprościej jakieś tutoriale:
https://www.geeksforgeeks.org/introduction-iterators-c/

jakiś przykład:

std::vector<int> arr = {4,3,5,2,1};

for (auto& i : arr)
    std::cout<<i<<" ";

Trochę do poczytania czym jest iterator, jest to desing pattern behavioralny:
https://refactoring.guru/design-patterns/iterator#:~:text=Iterator%20is%20a%20behavioral%20design,%2C%20tree%2C%20etc.).

Jak to jest implementowane w różnych językach, w twoim przypadku jak to zrobić w C++
https://www.internalpointers.com/post/writing-custom-iterators-modern-cpp

Tu masz listę standardowych struktur implementowanych w C++
https://cplusplus.com/reference/stl/

zkubinski napisał(a):

WIEM - tyle, że mi chodziło o to, chciałem się dowiedzieć czy iterator gdzieś na boku ma taką tablicę adresów i się do nich odwołuje iterując po obiektach ?
Bo wyobraziłem sobie sytuację, że mam gdzieś w kodzie powiedzmy 10 obiektów jakiegoś typu i chciałbym znaleźć je wszystkie

Jeśli masz blok pamięci std::vector, std::array to tam możesz przechowywać index i wyliczać adres wzorem, tak jest wykonywane przez procesor adres_początku_buffora + index * wielkość_elementu to ci daje adres elementu, oczywiście nie robisz tego tak ręcznie, tak się robi w assemblerze, w C++ możesz indexowania użyć square bracket []

Jeśli masz strutkturę typu linkedlist, to musisz przejść po elementach i możesz sobie trzymać stan aktualny gdzie skończyłeś wewnątrz iteratora.

Ogólnie musisz też trochę popracować nad strategią, bo lepiej zaplanować sobie drogę nauki w bardziej optymalny sposób.

0

@CloudPro:

Można dodać, że literatura odróżnia iteratory działajace "wg stanu zamrożonego" na moment ich powołania, oraz adaptujące się na żywo do zmian w kolekcji itd...
Chyba najtrudniejszym przypadkiem jest zachowanie się iteratora po skasowaniu bieżącego elementu, albo przypadek nie zachodzi (w klasycznej nieinteligentnej tablicy), albo się mówi, że działa, albo żeby tak nie robić itd...

generalnie robiąc "naiwnie" można zrobić tak lub tak, i nawet sobie nie uświadomić zagadnienia.

0

dzięki za odpowiedzi ale znowu będą od was ironiczne komentarze - zrozumiałem jak działa lista - napisałem taki kod - oczywiście nie obyło się bez pomocy z neta (a szkoda, bo usiłowałem sam to zrobić)

#include <iostream>

using namespace std;

class Node
{
public:
    Node() : description(string("null string")), nextNode(nullptr){}

    Node(Node &n){
        cout << "konstruktor kopiujacy" << endl;
        description = n.description;
        nextNode = n.nextNode;
    }

    Node &operator=(const Node &n){
        cout << "kopiujacy operator przypisania" << endl;
        description = n.description;
        nextNode = n.nextNode;

        return *this;
    }

    string description;
    Node *nextNode;
};

class List
{
public:
    List() : head(nullptr), tail(nullptr){}
    ~List(){
        delete tmp;
    }

    string showData(){
        return tail->description;
    }

    void addToList(const string &str){
        tmp = new Node;//przy każdym wywołaniu tej funkcji, tworzy się z nowym adresem obiekt Node
        tmp->description = str;

        if(head == nullptr){//przy pierwszym uruchomieniu funkcji i utworzeniu pierwszego obiektu "Node tmp",
                            //ten warunek sprawdza, czy adres pierwszego obiektu "tmp" został przypisany do "head" i "tail"
            head = tmp;
            tail = tmp;
        }
        else if(head != nullptr){//po drugim uruchomieniu funkcji i sprawdzeniu czy w pierwszym warunku wskaźnik "head" zawiera adres pierszego obiektu,
                                 //przypisany zostaje nowy adres drugiego, trzeciego i następnego obiektu "tmp"
            tail->nextNode = tmp;//tutaj dopisany zostaje adres nowy adres jako "następny" na liście
            tail = tail->nextNode;//tutaj zapamiętuję ten nowy adres
        }
    }

    Node *head, *tail, *tmp;
};

int main()
{
    List *list = new List;
    list->addToList("n1");
    cout << list->showData() << endl;

    list->addToList("n2");
    cout << list->showData() << endl;

    list->addToList("n3");
    cout << list->showData() << endl;

    cout << "Test" << endl;
    cout << "1 " << list->head->description << endl;
    cout << "2 " << list->head->nextNode->description << endl;
    cout << "3 " << list->head->nextNode->nextNode->description << endl;

    delete list;

    return 0;
}

a ten wątek założyłem, bo w poniższej części kodu przydałoby mi się coś co pozwoli mi odczytać zawartość w dowolnym elemencie listy (poniżej kawałek kodu o który mi chodzi) i pomyślałem, że przydałby się iterator i wyobraziłem sobie jego działanie w ten sposób, że te wskaźniki

tmp = new Node;

załadowałbym do jakiejś tablicy i potem je odczytywał (zamiast kombinować z tym poniżej)

cout << "1 " << list->head->description << endl;
cout << "2 " << list->head->nextNode->description << endl;
cout << "3 " << list->head->nextNode->nextNode->description << endl;
1

miałem skomentować np. dlaczego konstruktor kopiujący nie ma argumentów jako const, te if'y itd. Ale stwierdziłem że to bez sensu(tal lista nie jest nawet dokońcozna).

a ten wątek założyłem, bo w poniższej części kodu przydałoby mi się coś co pozwoli mi odczytać zawartość w dowolnym elemencie listy (poniżej kawałek kodu o który mi chodzi) i pomyślałem, że przydałby się iterator i wyobraziłem sobie jego działanie w ten sposób, że te wskaźniki

odpowiedz sobie na pytanie(i nam) po co ci struktura danych która w ogóle nie pasuje do twoich potrzeb.
a wystarczy sprawdzić to co jest w stl
https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/container/list/list
zadałeś sobie pytanie dlaczego lista nie ma operatora[] ?
na deser
https://www.geeksforgeeks.org/iterator-invalidation-cpp/

1

To nie chodzi o to, żebyś je grupował w tablicę. Dam tutaj uproszczoną implementację czegoś co przypomina iterator, żebyś zrozumiał:

class list_iterator {
    Node* node;
public:
    Node& operator*() { return *node; }
    void operator++() { node = node->next; }
    bool is_end() const { return node == nullptr; }
    list_iterator(List* l) { node = l->head; }
};

no i potem go używasz jakoś tak:

auto l = list_iterator(list);
while (!l.is_end()) {
    Node& n = *l;
    // tutaj możesz używać n
    l++;
}
0
revcorey napisał(a):

odpowiedz sobie na pytanie(i nam) po co ci struktura danych która w ogóle nie pasuje do twoich potrzeb.

Po to by wiedzieć, ciekawość, chęć rozumienia, bo taka z pozoru niby prosta lista trochę czegoś mnie nauczyła

a wystarczy sprawdzić to co jest w stl

wiem, co jest w STL, ba nawet więcej w Qt jest np QVector, QList, QMap etc...

zadałeś sobie pytanie dlaczego lista nie ma operatora[]

NIE, nawet mi to pytanie nie przyszło do głowy - a odpowiesz dlaczego ?

2

Po to by wiedzieć, ciekawość, chęć rozumienia, bo taka z pozoru niby prosta lista trochę czegoś mnie nauczyła

ale juz ci nie starczyło ciekawości na poczytaniu o liście.

NIE, nawet mi to pytanie nie przyszło do głowy - a odpowiesz dlaczego ?

podobno jesteś ciekawski?
Chcesz mi powiedzieć że rozpocząwszy implementację listy nie czytałeś czym ona jest? chyba zdajesz sobie sprawę jak są alokowane dane?
wystarczyło tylko po prostu poczytać o tym co chcesz zrobić
https://www.geeksforgeeks.org/linked-list-vs-array/
i inne strony które lepiej to tłumaczą.

0

@zkubinski dlaczego nie zainwestujesz w https://www.udemy.com/course/beg-modern-cpp/ ?

0

"zrobiłem tablicę na adresy określonego typu danych" nie ma czegos takiego jak adres na okreslony typ danych. dane zawsze sa tylko cyframi i nie ma innej fizycznej mozliwosci.

2
zkubinski napisał(a):

bawię się kodem i wymyślam różne rzeczy to jest kod z tylnej części ciała - bo chcę coś zrozumieć - zrobiłem tablicę na adresy określonego typu danych - chciałbym zapytać czy mniej więcej na tej zasadzie działa iterator ?

Napisałeś jakiś kod, i próbujesz go podciągnąć pod definicję "iterator".

Czyli robisz największy błąd znany w programowaniu. Zamiast tego powinieneś wyszukać informacje nt tego czym jest operator i po co się go używa, i ewentualnie potem próbować go napisać.

zkubinski napisał(a):

napisałem taki kod - oczywiście nie obyło się bez pomocy z neta (a szkoda, bo usiłowałem sam to zrobić)

Masz jakieś przekonanie że szukanie informacji, pomocy, przykładów, gotowych rozwiązań i kodu napisanego przez innych to słabość/przegrana? Bo niestety, ale właśnie z tego powodu że nie szukasz informacji w necie, tylko próbujesz wszystko pisać "sam" osiągasz tak słabe rezultaty w tym co robisz.

To nic złego czytać dokumentacją przez godzinę, obejrzeć tutorial w którym ktoś pokazuje dokładnie jak coś zrobić, użyć kodu napisanego przez kogoś innego - nic Ci z tego powodu nie ubędzie, nikt Cię nie ograbi z możliwości "napisania czegoś samemu"; a uchronisz się przed popularnymi błędami które są omawiane w każdym tutorialu a Ty je notorycznie popełniasz.

4

Usłyszałeś o czymś takim jak „szarlotka”, postanowiłeś usmażyć (sic) bez zaglądania do przepisów „żeby lepiej zrozumieć” i wyszła Ci przypalona i nieprzyprawiona potrawa mięsna.

Nie ma sensu, nawet dydaktycznego, a co dopiero praktycznego, próbować zrobić coś, co nie wie się, czym jest, bez wcześniejszego dowiedzenia się, co to takiego. Nawet bowiem, jak niepotrzebnie wielkim wysiłkiem Ci w końcu ta „szarlotka” zacznie wychodzić odpowiednio usmażona i przyprawiona, to to dalej nie będzie szarlotka w rozumieniu reszty społeczeństwa. Tak się nie nauczysz piec czy gotować, tak się nie nauczysz programować.

3

Wiecie, ja czegoś nie rozumiem...

Na pytanie

czy iterator działa na takiej zasadzie jak pokazałem w kodzie ?

Odpowiedź: NIE

Wątek można zamknąć ;)

0

Żeby iterator miał sens to musi operować na kolekcji obiektów. Stworzenie kilku, zupełnie ze sobą niepowiązanych obiektów nie jest kolekcją.

Sam iterator jest pojęciem abstrakcyjnym i nie da się odpowiedzieć, że jest on zrobiony tak i tak.
Iterator będzie inaczej zaimplementowany dla tablicy/wektora, inaczej dla listy, inaczej dla mapy a jeszcze inaczej dla strumienia.

6

Iterator, to jest nic innego jak jednolity interfejs na dostęp do sekwencyjnej kolekcji (czyli lista, tablica, zbiór, mapa, kolejka, wektor, stos). (Jakbyś się uparł to mógłbyś też do nie sekwencyjnych, jak drzewo albo graf, ale to byłoby dziwne). Jego główne zalety, to możliwość podmiany iterowanej kolekcji, bez konieczności edycji kodu iterującego - odseparowanie iteracji od samej kolekcji - również znane jako enkapsulacja. Wykorzystuje się do tego polimorfizm, i mając dostęp do danej kolekcji, można stworzyć jej iterator, i przekazać go dalej.

To co Ty napisałeś w pierwszym poście to jest kod podobny do niczego i który właściwie nie ma żadnego sensu. To co napisałeś, czyli "automatyczne znajdowanie elementów jakiegoś typu" to jest całkowity nonsens i bzdura (jasno pokazuje że usłyszałeś jakieś słowo, nie rozumiałeś co znaczy, i sam dopowiedziałeś sobie co to mogłoby być).

Poza tym, już pomijając temat iteratora, Twoja postawa jest z gruntu błędna. Nie robi się tak że piszesz jakiś kod, i potem mówisz "hmm, czy to co napisałem to jest (np) iterator?", tylko właśnie zupełnie odwrotnie - czyli najpierw szukasz informacji o tym czym jest iterator, doszkalasz się, i potem próbujesz go napisać.

A żeby jakoś merytorycznie odpowiedzieć na pytanie, to proszę tabelkę:

cecha iterator twór autorstwa @zkubinski
operuje na konkretnej kolekcji Tak Nie
otrzymuje kolekcję jawnie Tak Nie
przechowuje referencję bądź kopie Tak Tak
umożliwia iterowanie po wielu rodzajach kolekcji Tak Kto wie
ma standardową sygnaturę i jest znany w branży Tak Nie
używanie go jest niezależne od kolekcji Tak Kto wie
enkapsuluje bazową implementację kolekcji Tak Nie
jest wzorcem Tak Nie
ma sens Tak Nie

Tylko w jednej pozycji Twój twór się zgadza z iteratorem.

0

nie mam pojęcia jak rozumiesz dokumentację i zaszedłeś tak daleko bo drażni mnie to, że wypisujecie mi różne rzeczy nie rozumiejąc w ogóle tego co się do was pisze, a piszesz mi czy to co napisałem to jest (np) iterator? a czy czytałeś tytuł posta ? Czy na tej zasadzie działa iterator - chyba jest ogromna różnica co nie ?

5
zkubinski napisał(a):

nie mam pojęcia jak rozumiesz dokumentację i zaszedłeś tak daleko bo drażni mnie to, że wypisujecie mi różne rzeczy nie rozumiejąc w ogóle tego co się do was pisze, a piszesz mi czy to co napisałem to jest (np) iterator? a czy czytałeś tytuł posta ? Czy na tej zasadzie działa iterator - chyba jest ogromna różnica co nie ?

Dobrze, to podejdę do tematu inaczej - od podstawy.

Wyobraź sobie proszę taki scenariusz:

Piszesz program, który ma przechowywać powiedzmy listę plików w całym systemie operacyjnym. Dajmy na to że przechowujesz je w tablicy o dynamicznym rozmiarze, jest to główna część aplikacji, więc masz w programie 40 pętli for, które iterują po tej tablicy żeby coś z nią zrobić (przefiltrować, przemapować, etc.). Zauważasz że masz problem z wydajnością usuwania elementów z początku, więc podejmujesz decyzję, żeby zmienić tą tablicę z plikami na listę jednokierunkową - jakie to ma konsekwencje. No oczywiście takie, że teraz musisz zmienić swojego fora na while żeby iterować odpowiednio po liście jednokierunkowej. Potem podejmujesz decyzję, że jednak nie chcesz pisać swoich kolekcji, tylko używasz vectora z C++; i co musisz zrobić - znowu zmienić wszystkie swoje pętle na takie co używają .start() i .end().

W branży to się nazywanie niehermetyczność - bo struktura danych (tablica, lista, vektor) jest "widoczna" oraz "na wierzchu" i wszystko co z niej korzysta musi o niej wiedzieć - co ma taką niemiłą konsekwencję, że jeśli ta struktura się zmieni, to pętle też będą musiały się zmienić - wszystkie (a skoro i zmienić, to i przekompilować).

Jednym z rozwiązań na to byłby iterator - czyli wystawienie pewnego "pokrowca" na kolekcję, w taki sposób żeby Twoje pętle używały właśnie iteratora.

Scenariusz drugi:

Masz ten sam program, który ma dynamiczną tablicę z listą plików, ale Twoje 40 pętli nie iteruje po samej tablicy, tylko po iteratorze który wystawiłeś. Teraz chcesz zmienić tablicę na listę jednokierunkową - musisz więc zmienić iterator... i koniec. Nie ma więcej zmian. Jeśli iterator był w osobnym pliku .h, to nawet nie musisz rekompilować swoich pętli po takiej zmianie. Są oczywiście inne zalety iteratora, ale to jest taka główna.

Podsumowanie

I teraz sam sobie odpowiedz - wiedząc sens użycia iteratora - sam odpowiedz sobie na pytanie. Jak (do jasnej anielki) ma się Twój kod z pierwszego wątku do tej idei? Odpowiedź nasuwa się sama - Twój kod z pierwszego wątku oraz iterator nie mają ze sobą żadnego związku.

@zkubinski: Owszem, stworzyłeś pewnego rodzaju warstwę abstrakcji logicznej na iterowanie kolekcji - to Ci trzeba przyznać - ale po pierwsze w dosyć średni sposób; a po drugie nie każda warstwa abstrakcji na dostęp do kolekcji to od razu iterator.

zkubinski napisał(a):

zrobiłem tablicę na adresy określonego typu danych - chciałbym zapytać czy mniej więcej na tej zasadzie działa iterator ?

Jeśli chcesz się dowiedzieć "na jakiej zasadzie działa iterator" to zapoznaj się z: https://pl.wikibooks.org/wiki/C%2B%2B/Iteratory

zkubinski napisał(a):

nie mam pojęcia jak rozumiesz dokumentację i zaszedłeś tak daleko bo drażni mnie to, że wypisujecie mi różne rzeczy nie rozumiejąc w ogóle tego co się do was pisze, a piszesz mi czy to co napisałem to jest (np) iterator? a czy czytałeś tytuł posta ? Czy na tej zasadzie działa iterator - chyba jest ogromna różnica co nie ?

Dla mnie to wygląda jakbyś mi pokazał cztery kółka wciśnięte w kulkę plasteliny, i zapytał "czy na tej zasadzie działa samochód".

0
Riddle napisał(a):

@zkubinski: Owszem, stworzyłeś pewnego rodzaju warstwę abstrakcji logicznej na iterowanie kolekcji - to Ci trzeba przyznać - ale po pierwsze w dosyć średni sposób; a po drugie nie każda warstwa abstrakcji na dostęp do kolekcji to od razu iterator.
mnie to wygląda jakbyś mi pokazał cztery kółka wciśnięte w kulkę plasteliny, i zapytał "czy na tej zasadzie działa samochód".

jedyne zdanie które w jakiś sposób próbuje odpowiedzieć na założony temat i dalej mógłbym ciągnąć te zdanie aby dowiedzieć się czegoś więcej ale po co ? Jak zaraz będziecie się doszukiwać prywatnych korepetytorów, trolli czy innych takich...

0

No to cieszę się że udało mi się rozgryźć sedno problemu. Jeśli chcesz dowiedzieć się czegoś więcej to zadaj pytanie, postaram się odpowiedzieć w kulturalny sposób.

0

@Riddle: to nie jest sedno problemu - ale prawda jest taka, że jak ktoś chce prowadzić merytoryczną dyskusję, to da się ją prowadzić tylko musi być wola obu stron... ale dobra, nie chcę wylewać tu swoich żali, bo to nie ma sensu, a po drugie nic nie wniesie, a tyle postów reszta "mądrali" naprodukowała, że nawet gdyby były tu zawarte jakieś użyteczne informacje, to przez bełkot napisany tutaj nikomu nie będzie chciało się przez to przebijać

1

Wydaje mi się że zrozumiałem o co ci chodzi, z kodem:

#include <iostream>
#include <string>
using namespace std;
 
class AutoObjectList
{
	public:
	using spnode=AutoObjectList*;
	private:
	string title;
	spnode prev,next;
	struct Content
	{
		spnode head,tail;
		Content():head(nullptr),tail(nullptr) {}
		void insert(spnode object)
		{
			object->next=head;
			head=(head?head->prev:tail)=object;
		}
		void remove(spnode object)
		{
			(object->prev?object->prev->next:head)=object->next;
			(object->next?object->next->prev:tail)=object->prev;
		}
	};
	static Content &header()
	{
		static Content content;
		return content;
	}
	public:
	AutoObjectList(const string &title):title(title),prev(nullptr),next(nullptr)
	{
		header().insert(this);
	}
	AutoObjectList(const AutoObjectList &&object)=delete;
	AutoObjectList(const AutoObjectList &object):title(object.title),prev(nullptr),next(nullptr)
	{
		header().insert(this);
	}
	AutoObjectList &operator=(const AutoObjectList &object)
	{
		title=object.title;
		return *this;
	}
	virtual ~AutoObjectList()
	{
		header().remove(this);
	}
	ostream &prn(ostream &s)const { return s<<title<<endl; }
	friend ostream &operator<<(ostream &s,const AutoObjectList &object) { return object.prn(s); }
	static void show(ostream& s)
	{
		for(spnode i=header().head;i;i=i->next) s<<*i;
		//cout<<"*"<<endl;
		//for(spnode i=header().tail;i;i=i->prev) s<<*i;
		cout<<"================"<<endl;
	}
};

int main()
{
	{
		AutoObjectList a("kota"),b("ma"),c("Ala");
		AutoObjectList::show(cout);

		AutoObjectList *p1=new AutoObjectList("... p1 ...");
		AutoObjectList *p2=new AutoObjectList("... p2 ....");
		AutoObjectList::show(cout);

		delete p1;
		AutoObjectList::show(cout);
		delete p2;
		AutoObjectList::show(cout);

		AutoObjectList *tb[] = {new AutoObjectList("psa"), new AutoObjectList("ma"), new AutoObjectList("Ewa") };
		AutoObjectList::show(cout);

		for(AutoObjectList *p:tb) delete p;
		AutoObjectList::show(cout);
	}
	AutoObjectList::show(cout);
	return 0;
}

Z tym że to nie ma nić a nic wspólnego z iteratorami (oprócz tego że w części testowej został użyty standardowy iterator dla tablic);

0
_13th_Dragon napisał(a):

Wydaje mi się że zrozumiałem o co ci chodzi, z kodem:

tworzysz obiekt statyczny - który "pamięta" swój ostatni stan

static Content &header()
	{
		static Content content;
		return content;
	}

i w dość ciekawy sposób wypisujesz jakby "samego siebie"

static void show(ostream& s)
	{
		for(spnode i=header().head;i;i=i->next) s<<*i;
		//cout<<"*"<<endl;
		//for(spnode i=header().tail;i;i=i->prev) s<<*i;
		cout<<"================"<<endl;
	}

chciałbym na coś takiego wpaść... jak ty to robisz ?

4
zkubinski napisał(a):

chciałbym na coś takiego wpaść... jak ty to robisz ?

Każdy kto dobrze zna podstawy, jest w stanie z tych podstaw kombinować zaawansowane rzeczy.

0
_13th_Dragon napisał(a):

Nie, tych obiektów może być tysiące, zaś metoda show() nie należy do żadnego z nich, więc o jakiego "samego siebie" ci chodzi? Lepiej doczytaj o tym czym są statyczne metody, statyczne składowe oraz statyczne zmienne

no zgoda, już wyjaśniam o co mi chodzi. Tutaj tworzysz 3 różne obiekty

AutoObjectList a("kota"),b("ma"),c("Ala");

każdy z tych obiektów ma swoją własną niezależną metodę static Content &header() i dokładnie w tej metodzie tj. kolejno pobierasz adres aktualnie tworzonego obiektu using spnode=AutoObjectList*; i tu go chowasz -> spnode head,tail; i każdy z utworzonych obiektów a, b, c - trzyma swój adres

dlatego nazywam to "adresem do samego siebie" - i jak zaczniesz debugować taki wskaźnik, to zgodnie z oczekiwaniami będzie w nieskończoność pokazywał na samego siebie

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