Могут ли функции принимать абстрактные базовые классы в качестве аргументов?

Освоившись с идеей базовых классов и инкапсуляции, я начал понимать полиморфизм, но не могу понять, как заставить его работать. Многие из примеров, которые я просмотрел, на самом деле кажутся действительно принудительными (классы Foo и Bar слишком абстрактны, чтобы я мог видеть их полезность), но вот как я понимаю основную концепцию: вы пишете базовый класс, унаследовать от него целую кучу других вещей, которые изменяют то, что делают базовые методы (но не то, что они «есть»), затем вы можете написать общие функции для принятия и обработки любых производных классы, потому что вы несколько стандартизировали их внешний вид. Исходя из этого, я попытался реализовать базовую иерархию животных-> кошек / собак следующим образом:

class Animal {
  public:
    virtual void speak() = 0;
};

class Dog : public Animal {
  public:
    void speak() {cout << "Bark bark!" << endl;}
};

class Cat : public Animal {
  public:
    void speak() {cout << "Meow!" << endl;}
};

void speakTo(Animal animal) {
    animal.speak();
}

where speakTo может взять, может взять общий вид животного и заставить его говорить. Но, насколько я понимаю, это не работает, потому что я не могу создать экземпляр Animal (в частности, в аргументе функции). Тогда я спрашиваю, понимаю ли я основную полезность полиморфизма, и как я могу действительно делать то, что пытался сделать?

20
задан Connor Glosser 17 February 2012 в 12:57
поделиться