I\'m having a devil of a time understanding references. Consider the following code:
class Animal
{
public:
virtual void makeSound() {cout << \"rawr\"
Point 1: do not use references. Use pointers.
Point 2: the thing you have above is called a Taxonomy which is hierarchical classification scheme. Taxonomies are the exemplar of a kind which is utterly unsuitable for object oriented modelling. Your trivial example only works because your base Animal assumes all animals make a noise, and can't do anything else interesting.
If you try to implement a relation, such as
virtual bool Animal::eats(Animal *other)=0;
you will find you cannot do it. The thing is: Dog is not a subtype of Animal abstraction. The whole point of Taxonomies is that the classes of each level of the partition have new an interesting properties.
For example: Vertebrates have a backbone and we can ask whether it is made of cartiledge or bone.. we can't even ask that question of Invertebrates.
To fully understand, you must see that you cannot make a Dog object. After all, it's an abstraction, right? Because, there are Kelpies and Collies, and an individual Dog has to be of some species .. the classification scheme can be as deep as you like but it can never support any concrete individuals. Fido is not-a-Dog, that's just his classification tag.