[C++] Klasy i dziedziczenie


(Rdrfear) #1

Witam. Ostatnio zająłem się dziedziczeniem, ale chciałbym dowiedzieć się kilku rzeczy w związku z zadaniem jakie mam do wykonania.

  1. Czy jest możliwe stworzenie klasy i 3 klas pochodnych, które różnią się jedynie jedną zmienną i przechowywanie obiektów tych klas w jednej tablicy lub vectorze?

  2. Do metod i zmiennych klasy podstawowej w obiekcie klasy pochodnej dostajemy się tak jakby metody te i zmienne były w klasie pochodnej?

Dzięki za odpowiedzi.


(Wojtekbogocki) #2
  1. Tak. Tablica wskaźników na klasę bazową. Potem żeby sprawdzić jaka klasa pochodna jest przypisana pod dany indeks -> najlepiej jakiś identyfikator o innej wartości dla każdej z klas pochodnych. Po sprawdzeniu typu rzutujesz i masz.

  2. Tak.


(Marcinch7) #3

Tak, O ILE klasa została "wydziedziczona" używając operatora widoczności "public". W innym wypadku nie dobierzesz się do metod klasy bazowej.


(Rdrfear) #4

Dzięki - napisałem taką klasę i klasy pochodne. Program ma przedstawiać przedmioty i plecak z rgy rpg.

Niestety cały czas wyskakuje mi błąd, a ja nie wiem co jest nie tak. Czy ktoś mógłby rzucić okiem?

#include 


#define LOGUJK cout << "Obiekt utworzony." << endl

#define LOGUJD cout << "Obiekt usuniety." << endl

#define LOGUJM cout << "Metoda wykonana." << endl


using namespace std;


class Przedmiot

{

	private:

	string nazwa;

	double waga;

	double objetosc;


	public:

	Przedmiot(string s, double w, double o);

	~Przedmiot();


	double getWaga() { return waga; }

	double getObjetosc() { return objetosc; }


	void setWaga(double w);

	void setObjetosc(double o);

};


Przedmiot::Przedmiot(string s, double w, double o)

{

	this->nazwa = s;

	this->waga = w;

	this->objetosc = o;

	LOGUJK;

}


Przedmiot::~Przedmiot()

{

	LOGUJD;

}


void Przedmiot::setWaga(double w)

{

	this->waga = w;

}


void Przedmiot::setObjetosc(double o)

{

	this->objetosc = o;

}


class Bron : public Przedmiot

{

	private:

	int obrazeniaFizyczne;

	int szybkoscAtaku;


	public:

	Bron(string s, double w, double obj, int obr, int sz);

	~Bron();

};


Bron::Bron(string s, double w, double obj, int obr, int sz)

	:Przedmiot(s, w, obj)

{

	this->obrazeniaFizyczne = obr;

	this->szybkoscAtaku = sz;

}


Bron::~Bron()

{

}


class BronSieczna : public Bron

{

	private:

	int wytrzymalosc;


	public:

	BronSieczna(string s, double w, double obj, int obr, int sz, int wy);

	~BronSieczna();

};


BronSieczna::BronSieczna(string s, double w, double obj, int obr, int sz, int wy)

		   :Bron(s, w, obj, obr, sz)

{

	this->wytrzymalosc = wy;

}


BronSieczna::~BronSieczna()

{

}


class BronMiotana : public Bron

{

	private:

	int zasieg;

	int wytrzymalosc;


	public:

	BronMiotana(string s, double wa, double obj, int obr, int sz, int wy, int z);

	~BronMiotana();

};


BronMiotana::BronMiotana(string s, double wa, double obj, int obr, int sz, int wy, int z)

		   :Bron(s, wa, obj, obr, sz)

{

	this->wytrzymalosc = wy;

	this->zasieg = z;

}


BronMiotana::~BronMiotana()

{

}


class BronPalna : public Bron

{

	private:

	int zasieg;


	public:

	BronPalna(string s, double w, double obj, int obr, int sz, int z);

	~BronPalna();

};


BronPalna::BronPalna(string s, double w, double obj, int obr, int sz, int z)

		 :Bron(s, w, obj, obr, sz)

{

	this->zasieg = z;

}


BronPalna::~BronPalna()

{

}


class Pokarm : public Przedmiot

{

	private:

	int przywracaneHP;


	public:

	Pokarm(string s, double w, double o, int p);

	~Pokarm();

};


Pokarm::Pokarm(string s, double w, double o, int p)

	  :Przedmiot(s, w, o)

{

	this->przywracaneHP = p;

}


Pokarm::~Pokarm()

{

}


class Czary : public Przedmiot

{

	private:

	int obrazeniaMagiczne;

	int zasieg;


	public:

	Czary(string s, double w, double obj, int obr, int z);

	~Czary();

};


Czary::Czary(string s, double w, double obj, int obr, int z)

	 :Przedmiot(s, w, obj)

{

	this->obrazeniaMagiczne = obr;

	this->zasieg = z;

}


Czary::~Czary()

{

}


class Plecak

{

	private:

	double maxWaga;

	double maxObjetosc;

	double aktualnaWaga;

	double aktualnaObjetosc;

	int iloscPrzedmiotow;

	Przedmiot *p[30];


	public:

	Plecak(double mw, double mo);

	~Plecak();


	void wkladanieDoPlecaka(Przedmiot *t);

	void wyjmowanieZPlecaka(Przedmiot *t);

};


Plecak::Plecak(double mw, double mo)

{

	this->maxWaga = mw;

	this->maxObjetosc = mo;

	this->aktualnaWaga = 0;

	this->aktualnaObjetosc = 0;

	this->iloscPrzedmiotow = 0;

	LOGUJK;

}


Plecak::~Plecak()

{

	LOGUJD;

}


void Plecak::wkladanieDoPlecaka(Przedmiot *t)

{

	if(this->aktualnaWaga + t->getWaga() > this->maxWaga || this->aktualnaObjetosc + t->getObjetosc() > this->maxObjetosc)

	{

		cout << "Przedmiot ma za duza wage lub objetosc." << endl;

	} else {

		this->aktualnaWaga += t->getWaga();

		this->aktualnaObjetosc += t->getObjetosc();


		*p[iloscPrzedmiotow] = *t;

		this->iloscPrzedmiotow++;

	}

	LOGUJM;

}


void Plecak::wyjmowanieZPlecaka(Przedmiot *t)

{

	if(this->iloscPrzedmiotow == 0)

	{

		cout << "Plecak jest pusty." << endl;

	} else {

		for(int i=0;iiloscPrzedmiotow;i++)

		{

			if(t == p[i])

			{

				this->aktualnaWaga -= t->getWaga();

				this->aktualnaObjetosc -= t->getObjetosc();

				p[i] = p[i+1];

				this->iloscPrzedmiotow--;

				LOGUJM;

				break;

			}

		}

		cout << "Brak przedmiotu w plecaku." << endl;

	}


	LOGUJM;

}


int main()

{

	BronSieczna *siekierka = new BronSieczna("siekiera", 1.5, 2.7, 10, 22, 40);


	Plecak *plecaczek = new Plecak(40, 40);


	plecaczek->wkladanieDoPlecaka(siekierka);


	plecaczek->wyjmowanieZPlecaka(siekierka);


	delete siekierka;


	delete plecaczek;


	return 0;

}

(Marcinch7) #5

Może powiesz jaki to błąd?

Nie chce nam się czytać całego kodu.

Na oko widzę że korzystasz z obiektu "pol" który nie jest zadeklarowany :wink:

Do tego ja na twoim miejscu zamieniłbym np. "void Plecak::wyjmowanieZPlecaka(Przedmiot t)" to... na to: "void Plecak::wyjmowanieZPlecaka(Przedmiot *t)" ponieważ tworzysz wskaźnik na obiekt, a przy przekazywaniu go do parametru metody wyłuskujesz obiekt z tego wskaźnika co mija się z celem zupełnie.


(Rdrfear) #6

Poprawiłem kod, tak jak napisałeś. Problem tkwi chyba w metodzie klasy Plecak - wyjmowanie lub wkładanie. Kompilator nie zgłasza żadnych błędów, ale kiedy uruchamiam program wyskakują 2 komunikaty - o utworzeniu plecaka i siekiery. Potem wyskakuje błąd. Gdy spróbowałem debuggerem to wykryć to wyskoczyło: "W twoim programie zgłoszono naruszenie praw dostępu (błąd segmentacji)."

Nie wiem co tu może być nie tak.


(Marcinch7) #7

Wskaźników paniczu nie ogarniasz a nie dziedziczenia :wink:

#include 


#define LOGUJK cout << "Obiekt utworzony." << endl

#define LOGUJD cout << "Obiekt usuniety." << endl

#define LOGUJM cout << "Metoda wykonana." << endl


using namespace std;


class Przedmiot

{

   private:

   string nazwa;

   double waga;

   double objetosc;


   public:

   Przedmiot(string s, double w, double o);

   ~Przedmiot();


   double getWaga() { return waga; }

   double getObjetosc() { return objetosc; }


   void setWaga(double w);

   void setObjetosc(double o);

};


Przedmiot::Przedmiot(string s, double w, double o)

{

   this->nazwa = s;

   this->waga = w;

   this->objetosc = o;

   LOGUJK;

}


Przedmiot::~Przedmiot()

{

   LOGUJD;

}


void Przedmiot::setWaga(double w)

{

   this->waga = w;

}


void Przedmiot::setObjetosc(double o)

{

   this->objetosc = o;

}


class Bron : public Przedmiot

{

   private:

   int obrazeniaFizyczne;

   int szybkoscAtaku;


   public:

   Bron(string s, double w, double obj, int obr, int sz);

   ~Bron();

};


Bron::Bron(string s, double w, double obj, int obr, int sz)

   :Przedmiot(s, w, obj)

{

   this->obrazeniaFizyczne = obr;

   this->szybkoscAtaku = sz;

}


Bron::~Bron()

{

}


class BronSieczna : public Bron

{

   private:

   int wytrzymalosc;


   public:

   BronSieczna(string s, double w, double obj, int obr, int sz, int wy);

   ~BronSieczna();

};


BronSieczna::BronSieczna(string s, double w, double obj, int obr, int sz, int wy)

         :Bron(s, w, obj, obr, sz)

{

   this->wytrzymalosc = wy;

}


BronSieczna::~BronSieczna()

{

}


class BronMiotana : public Bron

{

   private:

   int zasieg;

   int wytrzymalosc;


   public:

   BronMiotana(string s, double wa, double obj, int obr, int sz, int wy, int z);

   ~BronMiotana();

};


BronMiotana::BronMiotana(string s, double wa, double obj, int obr, int sz, int wy, int z)

         :Bron(s, wa, obj, obr, sz)

{

   this->wytrzymalosc = wy;

   this->zasieg = z;

}


BronMiotana::~BronMiotana()

{

}


class BronPalna : public Bron

{

   private:

   int zasieg;


   public:

   BronPalna(string s, double w, double obj, int obr, int sz, int z);

   ~BronPalna();

};


BronPalna::BronPalna(string s, double w, double obj, int obr, int sz, int z)

       :Bron(s, w, obj, obr, sz)

{

   this->zasieg = z;

}


BronPalna::~BronPalna()

{

}


class Pokarm : public Przedmiot

{

   private:

   int przywracaneHP;


   public:

   Pokarm(string s, double w, double o, int p);

   ~Pokarm();

};


Pokarm::Pokarm(string s, double w, double o, int p)

     :Przedmiot(s, w, o)

{

   this->przywracaneHP = p;

}


Pokarm::~Pokarm()

{

}


class Czary : public Przedmiot

{

   private:

   int obrazeniaMagiczne;

   int zasieg;


   public:

   Czary(string s, double w, double obj, int obr, int z);

   ~Czary();

};


Czary::Czary(string s, double w, double obj, int obr, int z)

    :Przedmiot(s, w, obj)

{

   this->obrazeniaMagiczne = obr;

   this->zasieg = z;

}


Czary::~Czary()

{

}


class Plecak

{

   private:

   double maxWaga;

   double maxObjetosc;

   double aktualnaWaga;

   double aktualnaObjetosc;

   int iloscPrzedmiotow;

   Przedmiot *p[30];


   public:

   Plecak(double mw, double mo);

   ~Plecak();


   void wkladanieDoPlecaka(Przedmiot *t);

   void wyjmowanieZPlecaka(Przedmiot *t);

};


Plecak::Plecak(double mw, double mo)

{

   this->maxWaga = mw;

   this->maxObjetosc = mo;

   this->aktualnaWaga = 0;

   this->aktualnaObjetosc = 0;

   this->iloscPrzedmiotow = 0;

   LOGUJK;

}


Plecak::~Plecak()

{

   LOGUJD;

}


void Plecak::wkladanieDoPlecaka(Przedmiot *t)

{

   if(this->aktualnaWaga + t->getWaga() > this->maxWaga || this->aktualnaObjetosc + t->getObjetosc() > this->maxObjetosc)

   {

      cout << "Przedmiot ma za duza wage lub objetosc." << endl;

   } else {

      this->aktualnaWaga += t->getWaga();

      this->aktualnaObjetosc += t->getObjetosc();


      p[iloscPrzedmiotow] = t;

      this->iloscPrzedmiotow++;

   }

   LOGUJM;

}


void Plecak::wyjmowanieZPlecaka(Przedmiot *t)

{

   if(this->iloscPrzedmiotow == 0)

   {

      cout << "Plecak jest pusty." << endl;

   } else {

      for(int i=0;iiloscPrzedmiotow;i++)

      {

         if(t == p[i])

         {

            this->aktualnaWaga -= t->getWaga();

            this->aktualnaObjetosc -= t->getObjetosc();

            p[i] = p[i+1];

            this->iloscPrzedmiotow--;

            LOGUJM;

            break;

         }

      }

      cout << "Brak przedmiotu w plecaku." << endl;

   }


   LOGUJM;

}


int main()

{

   BronSieczna *siekierka = new BronSieczna("siekiera", 1.5, 2.7, 10, 22, 40);


   Plecak *plecaczek = new Plecak(40, 40);


   plecaczek->wkladanieDoPlecaka(siekierka);


   plecaczek->wyjmowanieZPlecaka(siekierka);


   delete siekierka;


   delete plecaczek;


   return 0;

}

Zmiana w metodzie wkładanie. Chociaż IMHO lepiej do plecaka list albo wektorów używać a nie tablic.


(Rdrfear) #8

Właśnie czasami zdarza mi się namieszać z tymi wskaźnikami. Z tego co widzę, muszę sobie o nich jeszcze poczytać. Dzięki.