Metody virtualne

0

Cześć,

zerknijcie proszę na ten kod:

#include <iostream>
#include <string>

class Wojsko {
public:
	Wojsko(void);
	~Wojsko(void);

	bool Atakuj(void);
};

Wojsko::Wojsko(void) {
}

Wojsko::~Wojsko(void) {
}

bool Wojsko::Atakuj(void) {
	std::cout << "Przeprowadzam atak!" << std::endl;

	return true;
}

class Snajper : public Wojsko {
public:
	Snajper(void);
	~Snajper(void);

	bool Atakuj(void);
};

Snajper::Snajper(void) {
}

Snajper::~Snajper(void) {
}

bool Snajper::Atakuj(void) {
	std::cout << "Celuje z ukrycia i strzelam!" << std::endl;

	return true;
}

void main(void) {
	Wojsko Czolg = Wojsko();
	Czolg.Atakuj();

	Snajper Wincent = Snajper();
	Wincent.Atakuj();

	system("PAUSE");
}

Według mojej książki jeśli w klasie potomnej pojawi się metoda o takiej samej nazwie jak w bazowej to kompilator zwróci błąd dlatego też istnieje coś takiego jak metody wirtualne, ale jak widzę w swoim przykładzie kompilator błędu nie zwraca, dlaczego? Z góry dzięki za pomoc.

0

Albo książka jest beznadziejna i błędna, albo nie zrozumiałeś. Normalnie nastąpi tutaj przesłonięcie funkcji, nic więcej. Problem o którym piszesz pojawia się gdy np. dziedziczysz z 2 klas i w każdej z nich masz metodę z takim samym prototypem, wtedy nie wiadomo której chcesz używać i masz błąd.
Temat który założyłeś NIE MA NIC WSPÓLNEGO z metodami wirtualnymi, więc po cholerę tytuł wątku to "metody wirtualne"?! Metody wirtualne służą do czegoś zupełnie innego.

Kwestie kosmetyczne:
int main() a nie void main()
Z tego co widzę to korzystasz z jakiejś starej ksiażki -> zmień ją na nową.

0

Dziwna książka... przesłonięcie nazw tu zadziała.

0

Ma wspólnego to, że właśnie o nich czytam...

NIE MA NIC WSPÓLNEGO
też chyba kiedyś zaczynałeś, więc po co te krzyki?

Kiedy dziedziczymy po klasie bazowej, można jedynie dodawać nowe metody. Jeżeli spróbujemy nadpisać zdefiniowaną funkcję, otrzymamy komunikat o błędzie.

0

A jeśli ja teraz czytam o dinozaurach to powinienem nazwać nowy wątek "Dinozaury"? ;)
A to co zacytowałeś jest zwyczajną nieprawdą, o czym zresztą sam sie przekonałeś. Możesz się pochwalić cóż to za książka pisze o takich cudach? (żeby jej komus przez przypadek kiedys nie polecić?)

0

Programowanie Gier Kompendium - Bruno Miguel

0

Czy może mi ktoś powiedzieć dlaczego ten kod nic nie wyświetla i czy moje myślenie jeśli chodzi o polimorfizm jest poprawne?

#include <iostream>

class Wojsko {
public:
	virtual void Atakuj(void) { };
};
//############################################
class Snajper : public Wojsko {
public:
	virtual void Atakuj(void);
};

void Snajper::Atakuj(void) {
	std::cout << "Celuje z ukrycia i strzelam!" << std::endl;
}
//############################################
class Jedi : public Wojsko {
public:
	virtual void Atakuj(void);
};

void Jedi::Atakuj(void) {
	std::cout << "Wyciagam miecz swietlny i robie ze wszystkich pasztet!" << std::endl;
}
//############################################
class Android : public Wojsko {
public:
	virtual void Atakuj(void);
};

void Android::Atakuj(void) {
	std::cout << "Wystrzelam rakiety i buuuuuuum!" << std::endl;
}
//############################################
int main(void) {
	Wojsko Armia[3];
	Armia[0] = static_cast<Wojsko>(Snajper());
	Armia[1] = static_cast<Wojsko>(Jedi());
	Armia[2] = static_cast<Wojsko>(Android());

	for(int a = 0;a < 3;a++) {
		Armia[a].Atakuj();
	}

	system("PAUSE");
	return 0;
}
0

@Sannin zamień tą ksiażkę na inną, bo ta jak widać jest totalnie do d**y. Polimorfizm działa tylko i wyłącznie ze wskaźnikami i referencjami. Jak przywalisz static_cast na klase bazową to następuje slicing -> obcięcie obiektu pochodnego do obiektu bazowego.

Poza tym chyba nie do konca rozumiesz ideę dziedziczenia, bo czy wg ciebie "Jedi" jest szczegolnym przypadkiem Wojska? o_O

#include <iostream>

class Wojownik
  {
  public:
    virtual void Atakuj()
    {

    }
  };
//############################################
class Snajper : public Wojownik
  {
  public:
    virtual void Atakuj();
  };

void Snajper::Atakuj()
{
  std::cout << "Celuje z ukrycia i strzelam!" << std::endl;
}
//############################################
class Jedi : public Wojownik
  {
  public:
    virtual void Atakuj();
  };

void Jedi::Atakuj()
{
  std::cout << "Wyciagam miecz swietlny i robie ze wszystkich pasztet!" << std::endl;
}
//############################################
class Android : public Wojownik
  {
  public:
    virtual void Atakuj();
  };

void Android::Atakuj()
{
  std::cout << "Wystrzelam rakiety i buuuuuuum!" << std::endl;
}
//############################################
int main()
{
  Wojownik* Armia[3];
  Armia[0] = new Snajper();
  Armia[1] = new Jedi();
  Armia[2] = new Android();

  for (int i = 0;i < 3;i++)
    {
      Armia[i]->Atakuj();
      delete Armia[i];
    }
  system("PAUSE");
  return 0;
}

0

W wypadku pierwszego problemu, jeśli chciałbyś wykorzystać metodę "Atakuj" z klasy bazowej musisz wykorzystać operator zasięgu:

Wincent.Wojsko::Atakuj();

w tedy wykona metodę z klasy bazowej. Taka ciekawostka ;p

0

Dzięki bardzo, Twój przykład działa muszę go tylko przeanalizować. Tutaj nie tyle chodziło mi o dziedziczenie co o polimorfizm, żeby to kompilator decydował o tym którą wersje z metod wybrać dla danego obiektu.

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