Lista dwukiernkowa, ktorej elementami są obiekty ( RÓŻNE ! )

0

Witam, serdecznie.
Streszczę krótko program:

  • Gra Monopoly/Eurobiznes (każdy wie o co chodzi)
  • Gra oparta na liście dwukierunkowej, z dziedziczeniem, polimorfizm etc.

Stworzyłem sobie zestaw klas. Każda opisuje inne Pola w Grze, mamy np. Miasto, Koleje, Szanse, Pola unikalne (Start, Podatek, Wiezienie) etc. Każda klasa ma w sobie swój własny konstruktor, który ustala nasze wartości jak Cena Zakupu, Sprzedazy, Ile domów etc.

I teraz jak to wszystko zaimplementować w LISTĘ DWUKIERUNKOWĄ, która przechowuje jak wiadomo element, jednego typu.
A ja mam 40 obiektów (tyle pól w grze) jak je przechowywać w jednej LIŚCIE, żeby później sprawnie się na niej obsługiwać i odwoływać do danych. Kombinowałem i kombinowałem bezsensownie. Ale nic z tego.

Mam sobie takie klasy

//--------LISTA DWUKIERUKOWA-----------------------------------------------------------------------
//--------------------------
class ElementListy {
 public:
	PUSTE POLE ! TU WLASNIE MUSZE ZADEKLAROWAC "COŚ" CO BEDE DODAWAŁ ! 
	ElementListy *nast, *pop;
};
//---------------------------
class CLista { 
 public:
	ElementListy *pocz, *kon, *nowy;
	
 	CLista(){pocz=NULL;}
 	
	void DodajElement(CMiasto *wsk, CSpecjalne *wsk2,int x)
	{	
		nowy = new ElementListy;
		nowy->pop = NULL;
		nowy->nast = NULL;
		if(pocz==NULL){ pocz=nowy; kon=nowy; }
		else { nowy->pop = kon; kon->nast = nowy; }
		kon=nowy;
	} 

A tak przykładowo wygląda jeden obiekt klasy Miasta, wywoływany z konstruktorem.

CMiasto(2,"Saloniki","Grecja",120,100,5,40,60,180,320,500,80,60);

Chcę takie coś dodawać do listy.

Ale mam też coś takiego, obiekt klasy Pola Podatku, który jest INNYM obiektem i też chciałbym żeby był TAKIM samym elementem listy dwukierunkowej.

CSpecjalne(39,"Podatek od nieruchmosci",200); 

Mam nadzieję, że ktoś zrozumie w czym rzecz, dzięki.

0

Każda klasa, której obiekt może się znaleźć na liście, powinien dziedziczyć po jednej klasie bazowej. Wtedy możesz przechowywać listę wskaźników na te elementy jako jeden kontener.

class CMiasto : public ElementListy
{
...
};
std::list<ElementListy*> Lista; 

Jeśli chcesz używać własnej implementacji listy, też możesz zrobić to w ten sposób.

0

Właśnie tak zaprojektowałem klasy, klasą bazową jest klasa POLE, każda kolejna dziedziczy po tej klasie i tak dalej.
Więc jeśli przyjmę sobie, że elementem tej listy będzie klasa Pole, to co dalej?
Nie rozumiem takiego zapisu :

std::list<ElementListy*> Lista; 

Mam sobie poszukać jakiegoś manuala z < > czymś takim? Chodzi o biblioteke STL?

0

Albo użyć gotowej listy z STL'a std::list
Albo napisać własną.

class ElementListy
  {
   public:
   KlasaBazowa *obiekt;
   ElementListy *nast, *pop;
  };

Inne klasy pochodzą od KlasaBazowa

0

Trochę niejasno napisałem.

Tak, chodzi o bibliotekę STL. W Twoim przypadku będzie to

 std::list<Pole*> lista;

lub to co napisał 13th Dragon (gdzie KlasaBazowa to Twoje Pole)

0

No dobra, ale jeśli zrobie coś takiego :

class ElementListy
  {
   public:
   KlasaBazowa *obiekt;
   ElementListy *nast, *pop;
  }; 

To skad kompilator bedzie wiedzial jaki obiekt chce dodac?

0

A nie musi wiedzieć.

#include <iostream>
using namespace std;

class List
  {
   public:
   class Base
     {
      public:
      virtual ostream &out(ostream &s)const { return s; }
      virtual ~Base() {}
     };     
   private:
   class Node
     {
      public:
      Base *obj;
      Node *next;
      Node(Base *obj,Node *next=0):obj(obj),next(next) {}
     };
   Node *first,*last;
   public:
   List():first(0),last(0) {}
   ~List();
   List &operator<<(Base *obj) { last=(last?last->next:first)=new Node(obj); return *this; }
   ostream &out(ostream &s)const;
  };
ostream &operator<<(ostream &s,const List::Base &B) { return B.out(s); }
ostream &operator<<(ostream &s,const List &L) { return L.out(s); }

ostream &List::out(ostream &s)const
  {
   for(Node *i=first;i;i=i->next) s<<*(i->obj);
   return s;
  }

List::~List()
  {
   for(;(last=first)!=0;delete last->obj,delete last) first=first->next;
  }


class X:public List::Base
  {
   virtual ostream &out(ostream &s)const { return s<<"J"; }   
   virtual ~X() { cout<<"T"; }
  };

class Y:public List::Base
  {
   virtual ostream &out(ostream &s)const { return s<<"A"; }
   virtual ~Y() { cout<<"A"; }
  };

class Z:public List::Base
  {
   virtual ostream &out(ostream &s)const { return s<<"K"; }   
   virtual ~Z() { cout<<"K"; }
  };

int main()
  {
     {
      List L;
      L<<new X()<<new Y()<<new Z();
      cout<<L<<"? ";
     }
   cout<<"!"<<endl;
   cin.sync();
   cin.get();
   return 0;
  };
0

Hym, dzięki wielkie, ale taki kod to średnio mi pomoże.
Zrobiłem tak :

//--------------------------
class ElementListy {
 public:
	CPole *Pole;
	ElementListy *nast, *pop;
};
//---------------------------
class CLista { 
 public:
	ElementListy *pocz, *kon, *nowy;
	
 	CLista(){pocz=NULL;}
 	
	void DodajElement(CPole *wsk)
	{	
		nowy = new ElementListy;
		nowy->Pole = wsk;
		nowy->pop = NULL;
		nowy->nast = NULL;
		if(pocz==NULL){ pocz=nowy; kon=nowy; }
		else { nowy->pop = kon; kon->nast = nowy; }
		kon=nowy;
	}
	void Dodaj()
 	{
		CPole *wsk;
		wsk = new CSpecjalne(1,"Start",400);
                DodajElement(wsk);
		wsk = new CMiasto(2,"Saloniki","Grecja",120,100,5,40,60,180,320,500,80,60);
                DodajElement(wsk);
	}
};
 

Jak teraz sprawdzić czy dobrze elementy zostaly dodane do listy ?
Zrobiłem coś takiego :

void Wyswietl()
	{
		while(pocz!=NULL)
		{
				cout<<"Nr Pola   : "<<pocz->Pole->Nr_Pola<<endl;
				cout<<"Nr Pola   : "<<pocz->Pole->Nr_Pola<<endl;
				cout<<"Nazwa Pola: "<<pocz->Pole->Nazwa_Pola<<endl;
				cout<<"Panstwo   : "<<pocz->Pole->Panstwo<<endl;
				cout<<"Wlasciciel: "<<pocz->Pole->Wlasciciel<<endl;
				cout<<"Cena zaupu: "<<pocz->Pole->Cena<<endl;
			pocz = pocz->nast;		
		}
	} 

Dostaje komunikat wtedy, że pocz->Pole->Panstwo, nie jest elementem klasy Pola i nie mogę tego wyświetlić.
Stwierdziłem, że zrobię w klasie metodę, która mi wyświetli odpowiednie Pola i tak :
W klasie CMiasto, którego obiekty dodaję mam :

	void virtual wyswietl()
	{
		cout<<"Nr Pola   : "<<Nr_Pola<<endl;
		cout<<"Nazwa Pola: "<<Nazwa_Pola<<endl;
		cout<<"Panstwo   : "<<Panstwo<<endl;
		cout<<"Wlasciciel: "<<Wlasciciel<<endl;
		cout<<"Cena zaupu: "<<Cena<<endl;
	}	 

Ale jak to wywołać teraz? :\

0

Musi być virtual jeszcze od CPole.
No i normalnie wywołujesz jak każdą inną metodę.

0

Wszystko działa, dzięki serdeczne. Stawiam piwo !

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