If I have a class called “Animal”, and a derived class “Bird : public Animal”, I can create a Bird these two ways:
Animal *sparrow = new Bird;
Bird *sparrow = new Bird;
Both compile fine and work as expected. Are they equivalent? Should I prefer one over the other?
The line, in itself, doesn’t demonstrate the difference. However, assume
Birddeclares a methodFlythat doesn’t exist onAnimal. You wouldn’t be able to do:on the other hand, this is legal:
The distinction here is a result of the fact that C++ is a statically typed language. The static type of the variable is what the compiler cares about when it’s verifying things like method calls. Since the static type of the variable
aisAnimalwhich doesn’t have aFlymethod, the compiler will not allow you to callFlyon it (not all animals are able to fly, so you’ll have to explicitly cast toBird:dynamic_cast<Bird*>(a)->Fly()is legal).The expression
new Birdwill have the typeBird*. If you assign a value of a derived type to a variable of a based type, the compiler will not complain (allBirds areAnimals, so it should always work). Basically, the compiler upcastsBird*toAnimal*. The reverse is not true. Not allAnimals areBirds, so you’ll have to take the responsibility and do the cast explicitly and tell the compiler that I know that object is really aBird*. Only in that case the compiler will let you to useBird-specific features. So, in general, if you need to use aBird-specific member, you’d better useBird* b = new Bird;.