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: 0, botów: 1

Robot: Semrush