Lista dwukierunkowa

0

Witam, mam problem z listą dwukierunkową zapewne błąd jest prosty, ale nie mogę go wykryć, może mógłby ktoś z forum udzielić porady.


void grupa::dodaj_studenta(student *podany)
{
    if (ile==0)
    {
        poczatek=podany;
        poczatek->poprz=NULL;
        poczatek->nast=NULL;
        wskaznik=poczatek;
        ile++;
         
    }

    else
    {
        wskaznik->nast=podany;
        podany->poprz=wskaznik;
        podany->nast=NULL;
        wskaznik=podany;
           ile++;
           
    }

}


void grupa::wyswietl()
{

wsk=poczatek;

while(wsk!=NULL)
{
    wsk->danestudenta();
    wsk=wsk->nast;
}
}

zaś w int main wywołuję ją następująco

nowa.dodaj_studenta(&dwa);
nowa.dodaj_studenta(&trzy);
nowa.dodaj_studenta(&cztery);
nowa.wyswietl();
jakas.dodaj_studenta(&dwa);

jakas.wyswietl();
nowa.wyswietl();

wynik na ekranie następujący
http://pokazywarka.pl/pgiwro/

nadpisuje się za każdym razem, dlaczego?

1

Nie wiem czy dobrze ci odpowiem ale sprawdź ;p

Z tego co widzę tu jest ok

nowa.dodaj_studenta(&dwa);
nowa.dodaj_studenta(&trzy);
nowa.dodaj_studenta(&cztery);
nowa.wyswietl(); 

ale zobacz tu :

jakas.dodaj_studenta(&dwa);

i zobacz co ci robi z obiektem &dwa

 if (ile==0)
    {
        poczatek=podany;
        poczatek->poprz=NULL;
        poczatek->nast=NULL;
        wskaznik=poczatek;
        ile++;
 
    }

I po tym działaniu edytowałeś wskażnik na obiekt dwa

Obie listy odwołują się do tego samego wskaźnika więc jak w "jakas" edytowałeś wskaźnik to nowa będzie odwoływać się do już zmienionej wersji ;)

0

a masz jakiś pomysł jak naprawić to? chciałem utworzyć w klasie obiekt studenta i przypisać do niego tego wywoływanego, aby nie pracować na oryginale, ale coś nie bardzo to poszło.

0

Hmm nie pamiętam jak w c++ z przekazywaniem obiekty do funkcji ale mozesz w klasie zrobić metodę Kopią w której będzie tworzyły nowego studenta do którego przepiszesz ustawienia z obiektu sdo nowo utworzonego obiektu i zwrócisz nowo utworzony obiekt :p
Pisze z telefonu :p

0

spróbuję jeszcze inaczej, ale to co mówisz nie zadziała, gdyż obiekt student ma przechowywać informacje o nazwie grup do jakich należy i aby to uzyskać muszę do funkcji dodającej studenta do grupy(tam też dodawana jest nowa nazwa grupy do jego starych) wysłać jego oryginał przez referencję, jeśli wyślę kopię to może powiedzie się to Twoje z listą, ale wtedy wyślę przez wartość -> uruchomi się konstruktor kopiujący i stracę kontakt z oryginałem, nazwa grup nie ulegnie zmianie(pomimo, że dodam aktualną) i będzie taka jak w momencie wysłania do metody w klasie.

2

Twoje problemy od razu by zniknęły gdybyś zamiast parametru student* pobrany użył const student const* pobrany lub może lepiej const student& pobrany. Wtedy nie ma mowy, żebyś mógł zmodyfikować źródło, a błąd wylazłby na wierzch od razu. Ustal sobie takie tworzenie parametrów metod jako zasadę wstępną. Co do rozwiązania, to Twoim błędem jest to, że dane, które chcesz wpakować są jednocześnie częścią struktury listy. U Ciebie student jest elementem listy, ale i jednocześnie węzłem tej listy. Nie da się tego rozwiązać bez każdorazowego kopiowania. Dlatego elementami list robi się osobne struktury takie jak node, których jednym z pól poza wskaźnikiem do kolejnych/poprzednich elementów jest wskaźnik lub referencja do przechowywanego elementu.
Krótko mówiąc oderwij pola nast i poprz od studenta.
Zrób sobie osobną małą zagnieżdżoną klasę lub strukturę wewnątrz grupa np.:
struct node { student* dane; struct node* nast, poprz; }, wypełniaj takie obiekty danymi i dowiązuj je jako kolejne elementy listy. A jeszcze lepiej jest oderwać listę od grupa. Np. przez zdefiniowanie:

public class student_list
{
private:
	struct node
	{
		student* dane;
		struct node* nast, poprz;
	};
	struct node* poczatek;
public:
	/*...tutaj definicje metod (dodaj, usuń itp.) obsługujących tę listę...*/
}

To oczywiście nie oznacza, że student będzie zawierał tylko jego dane osobowe - student może być również obiektem lub strukturą zawierającym wskaźniki do grup, prowadzących, gimbusów i co tam sobie jeszcze wymyślisz, oprócz danych osobowych takich jak np. dane_studenta* (lub może dane_studenta& - bo takie dane muszą istnieć, aby student istniał).

0

dzięki za pomoc, ja zrobiłem na wektorze i działa poprawnie


vector <student> tab;

void grupa::dodaj_studenta(student *podany,int ile)
{
    nie_pusty=true;
n=ile;
if (podany->nazwa_gr=="")
   {

   podany->nazwa_gr=nazwa_grupy;
}
else podany->nazwa_gr+=nazwa_grupy;
  tab.push_back(*podany);


}


void grupa::wyswietl()
{
    if (nie_pusty==true)
   {
        for (int i=0; i<n; i++)
      tab[i].danestudenta();
}
    else cout<<"brak studentow ";

cout<<endl;

}

 
0
michcio19923 napisał(a):
nowa.dodaj_studenta(&dwa);
nowa.dodaj_studenta(&trzy);
nowa.dodaj_studenta(&cztery);
nowa.wyswietl();
jakas.dodaj_studenta(&dwa);

jakas.wyswietl();
nowa.wyswietl();

W zależności od tego co oczekujesz w listach "nowa" i "jakaś" błąd leży gdzie indziej.

  • Jeżeli oczekujesz że student "dwa" będzie należeć do obu list to: funkcja dodaj_studenta powinna przyjmować referencje i robić kopię tego studenta.
  • Jeżeli oczekujesz że student "dwa" przeniesie się do listy "jakaś" to: obiekt student musi mieć wskaźnik na swoją listę i w funkcji dodaj_studenta najpierw usuwa studenta ze starej listy.

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