Data Structures and Algorithms with Object-Oriented Design Patterns in C++

## Run-Time Type Information and Casts

Consider the following declarations which make use of the Rectangle and Square classes defined in Program :

```Rectangle r (Point (0,0), 5, 10);
Square s (Point (0,0), 15);```
Clearly, the assignment
`r = s;`
is valid because Square is derived from Rectangle. I.e., since a Square is a Rectangle, we may assign s to r.

On the other hand, the assignment

`s = r;`
is not valid because a Rectangle instance is not necessarily a Square.

Consider now the following declarations:

```Rectangle& r = *new Square (Point (0,0), 20);
Square s;```
The assignment s=r is still invalid because r is a reference to a Rectangle, and a Rectangle instance is not necessarily a Square, despite the fact that in this case it actually is!

In order to do the assignment, it is necessary to convert the type of r from a reference to a Rectangle to a reference to a Square. This is done in C++ using a cast operator :

`s = (Square&) r;`
However, a conversion like this is unchecked. Neither the compiler nor the run-time system can determine whether r actually refers to a Square.

To determine the actual type of the object to which r refers, we must make use of run-time type information   . In C++ every object instance of a class that has virtual functions keeps track of its type. We can test the type of such an object explicitly using the C++ typeid operator like this:

```if (typeid (r) == typeid (Square))
s = (Square&) r;```
This code is type-safe because the cast is only done when the object to which r refers actually is a Square.

C++ also provides a type-safe cast operator called dynamiccast<T>() . In this case, T must either a pointer type or a reference type. The dynamiccast operator combines the run-time type-compatibility check with the type cast operation. For example, the statement

`s = dynamic_cast<Square&> (r);`
succeeds if r is found at run-time to be is an instance of the Square class. If it is not, the dynamiccast operator throws a badcast  exception. (Exceptions are discussed in Section ).