This is a problem called slicing.
Dog() creates a Dog object. If you need to call Dog().makeSound() , it will print a βbarkβ as you expect.
The problem is that you initialize badDog , which is an object of type Animal , with this Dog . Since Animal can only contain Animal , and not anything derived from Animal , it accepts the Animal part of Dog and initializes itself with it.
The type of badDog always Animal ; it can never be anything else.
The only way you can get polymorphic behavior in C ++ is to use pointers (as you demonstrated with the goodDog example) or using links.
A reference (e.g., Animal& ) can refer to an object of any type derived from Animal , and a pointer (e.g., Animal* ) can point to an object of any type derived from Animal . A simple Animal , however, is always Animal , nothing more.
Some languages, such as Java and C #, have reference semantics, where variables (in most cases) are just references to objects, so given Animal rex; rex is actually just a reference to some Animal and rex = new Dog() makes rex reference to a new Dog object.
C ++ does not work like this: variables are not objects in C ++, variables are objects. If you say rex = Dog() in C ++, it copies the new Dog object to rex , and since rex is of type Animal , it is sliced ββand parts of Animal copied. They are called semantics of values, which are used by default in C ++. If you need reference semantics in C ++, you need to explicitly use references or pointers (none of them match references to C # or Java, but they are more similar).
James McNellis Dec 09 '10 at 22:24 2010-12-09 22:24
source share