[C++] Klasa - wypisywanie na ekran


(Rdrfear) #1

Mam mały problem z wypisywaniem na ekran elementów ze struktury umieszczonej w klasie.

//EDIT sorry za wcześniejszy kod, ale pomieszałem 2 różne kody, tak to jest jak się coś robi w pośpiechu.

Prawidłowy Kod:

#include 


struct Osoba

{

	enum Plec{K,M};

	Osoba(Plec p) : plec(p) {}

	Plec plec;

};


class Kolko

{

	public:

	Kolko();

	~Kolko();

	bool pusta();

	bool usunPierwszy();

	unsigned int dolacz(Osoba* s);

    void uczestnicy() const;

    bool czyJest(Osoba* osoba, unsigned int n);


private:

	struct Link

	{

		Osoba* s;

		Link* next;

		Link* prev;

		bool prowadzacy;

		unsigned int iden;

		Link(Osoba* s = 0, Link* next = 0, Link* prev = 0, bool prowadzacy = 0, unsigned int iden = 0)

		{

			this->s = s;

			this->next = next;

			this->prev = prev;

			this->prowadzacy = prowadzacy;

			this->iden = iden;

		}

	}; Link* head;

};


unsigned int identyfikator = 0;


Kolko::Kolko()

{

	head = new Link(0, NULL, NULL, 1, 0); //tworzymy prowadzacego, unikalny char jego to pp, identyfikator 0 i oznaczenie typu bool, ze to on

}


Kolko::~Kolko()

{

	while(!pusta())

		usunPierwszy(); //usuwanie

}


bool Kolko::pusta()

{

	return head == 0;

}


bool Kolko::usunPierwszy()

{

	if(pusta())

		return false;


	Link* pos = head->next;

	delete head;

	head = pos;

	return true;

}


unsigned int Kolko::dolacz(Osoba* osoba)

{

	if(czyJest(osoba, 0)) //jesli osoba w kolku zwroc 0, napisalem taka funkcje i dziala

		return 0;


	Link* pos = head; // za pomoca pos dochodzimy do prowadzacego, bo uczestnicy nowi dolaczaja tak by byc jego lewym sasiadem

	while(pos->prowadzacy != 1)

	{

		pos = pos->next;

	}

	identyfikator++;

	Link* tmp = new Link(osoba, pos, pos->prev, 0, identyfikator); //nadajemy kazdemu nowemu nowy identyfikator

	pos->prev = tmp;


	return identyfikator; //zwracamy identyfikator

}


void Kolko::uczestnicy() const

{

	Link* pos = head; //mamy wypisywac od lewego sasiada prowadzacego, bez niego samego

	while(pos->prowadzacy != 1)

	{

		pos = pos->next;

	}


	while(pos->prev != NULL) //wypisujemy od lewego sasiada

	{

		std::cout <<"plec: " << pos->s->plec << ", nr: " << pos->iden << "\n";

		pos = pos->prev;

	}

} 


bool Kolko::czyJest(Osoba* osoba, unsigned int n)

{

	Link* pos = head;

	if(osoba != 0)

	{

		while(pos->next != NULL)

		{

			if(pos->s == osoba)

			{

				return true;

			}

			pos = pos->next;

		}

		return false;

	} else {

		while(pos->next !=NULL)

		{

			if(pos->iden == n)

			{

				return true;

			}

			pos = pos->next;

		}

		return false;

	}

}

Podczas testowania takim czymś:

Kolko s;

Osoba p(Osoba::K);

Osoba q(Osoba::M);

s.dolacz(&p);

s.dolacz(&q);

s.uczestnicy();

Program się crashuje. Konczy aplikację i tyle. Kompilator milczy - kwestia błędnego zapisania kodu przeze mnie - wpatrywanie w kod niestety nic mi nie daje, jedynie oczy zaczynają mnie boleć.


(tomms) #2

Pokaż program który się *przynajmniej* kompiluje.

Link(char s = pp, Link* next = 0, Link* prev = 0, bool prowadzacy = 0, unsigned int iden = 0)

      {

         this->s = s;

nie zdefiniowane pp, s i this-> są innego typu

unsigned int Kolko::dolacz(char s[2])

{

   if(czyJest(s, 0)) //jesli osoba w kolku zwroc 0, napisalem taka funkcje i dziala

      return 0;

dolacz ma inną deklarację w klasie (bierze jeden parametr char a nie tablice), nie zdefiniowana metoda czy Jest()

Link* tmp = new Link(z, pos, pos->prev, 0, 0, identyfikator); //nadajemy kazdemu nowemu nowy identyfikator

Nie prawidłowa liczba parametrów dla konstruktora.

void Chusteczka::uczestnicy() const

co to za klasa Chusteczka?

Kolko s;

s.dolacz(op);

s.dolacz(cd);

s.uczestnicy();

Nie zdefiniowane op i cd.


(Blapiter) #3

Błąd - Head nie ma osoba czyli null pointer exeption :stuck_out_tongue:

while(pos->prev != NULL) //wypisujemy od lewego sasiada

   {

      std::cout <<"plec: " << pos->s->plec << ", nr: " << pos->iden << "\n";

      pos = pos->prev;

   }

W c++ nie używa się już słowa "NULL" tylko poprostu 0. Działający kod :

#include 

#include 


using namespace std;


    struct Osoba

    {

       enum Plec{K,M};

       Osoba(Plec p) : plec(p) {}

       Plec plec;

    };


    class Kolko

    {

       public:

       Kolko();

       ~Kolko();

       bool pusta();

       bool usunPierwszy();

       unsigned int dolacz(Osoba* s);

        void uczestnicy() const;

        bool czyJest(Osoba* osoba, unsigned int n);

        static unsigned int identyfikator; // ZMIENNA STATYCZNA

    private:

       struct Link

       {

          Osoba* s;

          Link* next;

          Link* prev;

          bool prowadzacy;

          unsigned int iden;

          Link(Osoba* s = 0, Link* next = 0, Link* prev = 0, bool prowadzacy = 0, unsigned int iden = 0)

          {

             this->s = s;

             this->next = next;

             this->prev = prev;

             this->prowadzacy = prowadzacy;

             this->iden = iden;

          }

       };

        Link* head;

    };


    unsigned int Kolko::identyfikator = 0; // INICJALIZACJA STATYCZNEJ


    Kolko::Kolko()

    {

       head = new Link(0, 0, 0, 1, 0); 

    }


    Kolko::~Kolko()

    {

       while(!pusta())

          usunPierwszy(); //usuwanie

    }


    bool Kolko::pusta()

    {

       return head == 0;

    }


    bool Kolko::usunPierwszy()

    {

       if(pusta())

          return false;


       Link* pos = head->prev; // DODAJESZ DO TYŁU WIEC KASOWANIE TEŻ DO TYŁU

       delete head;

       head = pos;

       return true;

    }


    unsigned int Kolko::dolacz(Osoba* osoba)

    {

       if(czyJest(osoba, 0))

          return 0;


       Link* pos = head;   

       while(pos->prowadzacy != 1)

       {

          pos = pos->next;

       }

       ++identyfikator;

       Link* tmp = new Link(osoba, pos, pos->prev, 0, identyfikator);  

       pos->prev = tmp;


       return identyfikator; // NIE WIEM PO CO MA BYC ZWRACANY ?

    }


    void Kolko::uczestnicy() const

    {

       Link* pos = head;   

       while(pos->next != 0)

       {

          pos = pos->next;

       }


       while(pos != 0) // pos != 0

       {

          if(pos->s != 0) // HEAD NIE MA OSOBA

          std::cout <<"plec: " << pos->s->plec << ", nr: " << pos->iden << "\n";

          else

          std::cout << "Bez osoba" << endl;

          pos = pos->prev;

       }

    }


    bool Kolko::czyJest(Osoba* osoba, unsigned int n)

    {

       Link* pos = head;

       if(osoba != 0)

       {

          while(pos->next != 0)

          {

             if(pos->s == osoba)

             {

                return true;

             }

             pos = pos->next;

          }

          return false;

       } else {

          while(pos->next !=0)

          {

             if(pos->iden == n)

             {

                return true;

             }

             pos = pos->next;

          }

          return false;

       }

    }



int main(int argc, char *argv[])

{

Kolko s;


Osoba p(Osoba::K);

Osoba q(Osoba::M);


s.dolacz(&p);

s.dolacz(&q);


s.uczestnicy();


cin.sync();

cin.get();

return 0;

}

(Rdrfear) #4

Dzięki, teraz faktycznie działa.

Mam jeszcze jeden problem z funkcją w klasie, która liczy ile osób jest w kółku, bez prowadzącego.

Jak testuję tym wcześniejszym testem i dam std::cout << h.ilosc(); Na ekran wypluwa mi liczbę 4297453. Powinno być 2.

Sama funkcja ilosc().

unsigned int Kolko::ilosc() const

{

	Link* pos = head;

	int ilosc;


	while(pos->prev != 0) //jesli ma sasiada

	{

		ilosc++;

		pos = pos->prev;

	}


	return ilosc;

}

/EDIT nie wierzę, że popełniłem taki głupi błąd. Dzięki.


(Blapiter) #5

Nie zainicjowałeś zmiennej 'ilosc' wartością 0, system przy inicjalizacji "wrzuca" tam cokolwiek

unsigned int Kolko::ilosc() const

{

   Link* pos = head;

   int ilosc=0;//TU


   while(pos->prev != 0) //jesli ma sasiada

   {

      ilosc++;

      pos = pos->prev;

   }


   return ilosc;

}

(Rdrfear) #6

Najprawdopodobniej zamęczę kogoś dzisiaj tym co piszę, ale nic nie poradzę.

Napisałem funkcję, która dodaje mi do head elementy do przodu.

Przyjmuje osobę i numerek n (n oznacza, którym elementem od head'a ma być, np. 0 - prawy sąsiad head'a, 1 - prawy sąsiad prawego sąsiada head'a).

Kiedy wrzucam:

Osoba p(Osoba::K);

Osoba q(Osoba::M);

Osoba r(Osoba::K);

Osoba s(Osoba::M);

h.dolacz(&p);

h.dolacz(&q);

h.dolacz(&r, 0);

h.dolacz(&s, 1);

h.ilosc();

h.uczestnicy();

Wyrzuca:

plec: 1 nr: 2

plec: 0 nr: 1

plec: 0 nr: 3 - powinno wypisac 1 jeszcze

3 - powinno byc o 1 wiecej

unsigned int Kolko::dolacz(Osoba* osoba, unsigned int n)

{

	if(ilosc() <= n)

		return 0;

	if(osoba == 0)

		return 0;

	if(czyJest(osoba, 0))

		return 0;



	if(n == 0) // jesli 0 to dodajemy bezposrednio z prawej strony head'a

	{

		identyfikator++;

		Link* tmp = new Link(osoba, head->next, head, 0, 0, identyfikator);

		head->next = tmp;

	} else { //jesli wieksza od 0 

               Link* pos = head;

		for(unsigned int i=0;i==n;i++) // przechodzimy na miejsce, przed ktorym mamy nowy element wcisnac

		{

			pos = pos->next;

		}

		identyfikator++;

		Link* tmp = new Link(osoba, pos->next, pos, 0, 0, identyfikator);

		pos->next = tmp;

	}


	return identyfikator;

}