Dziedziczenie wywołanie przesłoniętej metody.

0

Cześć, nie rozumiem czemu wywołuje mi się metoda klasy bazowej, a nie pod klasy. Mam klasę Animal która rozszerza mi klasę Cat. W klasie Cat przesłaniam metodę getVoice. Mam również klasę Herd, w której trzymam swoje zwierzęta. Jest tam także metoda getVoice, która powinna wywoływać odpowiednie metody podklas. Przeciążyłem również operator dodawania, żebym mógł łatwo dodawać zwierzęta do stada. Tak wygląda całość:

class Cat : public Animal
{
public:
	Cat();
	virtual std::string getVoice();
	~Cat();
};

Cat::Cat()
{
}

std::string Cat::getVoice()
{
	return "miau";
}

Cat::~Cat()
{
}

class Animal
{
public:
	Animal();
	virtual std::string getVoice();
	~Animal();
};

Animal::Animal()
{
}

std::string Animal::getVoice()
{
	return "Animal";
}

Animal::~Animal()
{
}

class Herd
{
public:
	Herd();
	std::string getVoice();
	~Herd();

	Herd operator+(Animal& animal);

private:
	std::vector <Animal> herd;
};

Herd::Herd()
{
}

std::string Herd::getVoice()
{
	std::string voices = "";
	for (int i = 0; i < herd.size(); i++)
	{
		voices += herd[i].getVoice();
	}
	return voices;
}

Herd::~Herd()
{
}

Herd Herd::operator+(Animal& animal)
{
	herd.push_back(animal);
	return *this;
}

int main()
{
	Herd *herd = new Herd();
	Cat * cat = new Cat();
	*herd + *cat;
	cout << herd->getVoice();
	//	cout << cat->getVoice();

	cout << "\n\n";

}

Gdy uruchomię prinuje mi Animal :/

0

Ponieważ klasa Animal jest deklarowana po Cat, Cat nie wie o jej istnieniu. Przenieś deklarację klasy Animal na początek pliku.

1
 std::vector <Animal> herd; [...] voices += herd[i].getVoice(); 

Masz vector of Animal, a Animal potrafi tylko wołać "Animal". typeid(herd[i]) == typeid(Animal)

0

Hmm no rozumiem, ale nie czaję teraz jak mam przechowywać obiekty pod klasy animal. Czemu nie jest wywoływana metoda odpowiedniej klasy?

0

Ok już rozumiem zmieniłem sobie metodę getVoice, ale mam jeszcze problem z przeciążeniem operatora dodawania bo wolałbym jednak robić to przez referencje, a nie wskaźnik. Takie mam zalecenie od górne. Jest jakiś sposób na to? Teraz wygląda to u mnie tak

class Herd
{
public:
	Herd();
	std::string getVoice();
	~Herd();

	Herd operator+(Animal* animal);

private:
	std::vector <Animal*> herd;
};

std::string Herd::getVoice()
{
	std::string voices = "";
	for (int i = 0; i < herd.size(); i++)
	{
		voices += herd[i]->getVoice();
	}
	return voices;
}



Herd Herd::operator+(Animal* animal)
{
	herd.push_back(animal);
	return *this;
}

I ładnie działa, ale tak jak wspomniałem wolał bym referencję. Jest taka możliwość?

1

To się skończy wyciekiem pamięci.
Używaj scopeed_ptr lub shared_ptr (c++ 11).

3
  1. Musisz używać obiektów polimorficznych, żeby korzystać z polimorfizmu. Tj referencja na Animal lub wskaźnik na Animal. Ponadto Animal::getVoice zrobiłbym czysto wirtualne. No bo czy jest jakiś uniwersalny dźwięk wydawany przez każde zwierze? Chyba nie.
  2. Bardzo niekonsekwentny ten Twój Herd::operator+. Nikt się raczej nie spodziewa, że taki operator będzie modyfikowal obiekt. Już raczej operator+=, choć to też nie za fajne rozwiązanie.

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