(RTTI) & Casting Operator in C++

19
Run-Time Type ID and the Casting Operators

Transcript of (RTTI) & Casting Operator in C++

Page 1: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 1/19

Run-Time Type ID and the

Casting Operators

Page 2: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 2/19

Run-Time Type Identification

(RTTI) Added to provide enhanced support for run-time

polymorphism.

To identify the type of an object during the

execution of program.

Reason for req:

 ± Because of polymorphism, the precise nature of that

object is not determined until the program is

executed.

 ± base-class pointers may be used to point to objects of 

the base class or any object derived from that base

Page 3: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 3/19

object's type can be obtained using typeid.

It is defined in the header <typeinfo>

There are two ways to extract typeid

Prototype: ± typeid(object )

It may be of any type,including the built-in types and

class types that you create.

typeid returns a reference to an object of type type_infothat describes the type of object .

Page 4: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 4/19

The type_info class defines the following public

members:

bool operator==(const type_info &ob);

bool operator!=(const type_info &ob);

bool before(const type_info &ob); /* internal use*/

const char *name( ); /*returns a pointer to the name of 

the type.*/

Page 5: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 5/19

// A simple example that uses typeid.

#include <iostream>

#include <typeinfo>

using namespace std;

class myclass1 {// ...

};

class myclass2 {

// ...

};

int main()

{int i, j;

float f;

char *p;

myclass1 ob1;

myclass2 ob2;

cout << "The type of i is: " << typeid(i).name<< endl;cout << "The type of f is: " << typeid(f).name() << endl;

cout << "The type of p is: " << typeid(p).name() << endl;

cout << "The type of ob1 is: " << typeid(ob1).name() << endl;

cout << "The type of ob2 is: " << typeid(ob2).name() << "\n\n";

if(typeid(i) == typeid(j))

cout << "The types of i and j are the same\n";

if(typeid(i) != typeid(f))cout << "The types of i and f are not thesame\n";

if(typeid(ob1) != typeid(ob2))

cout << "ob1 and ob2 are of differing types\n";

return 0;

}

Page 6: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 6/19

Output:The type of i is: int

The type of f is: floatThe type of p is: char *

The type of ob1 is: class myclass1

The type of ob2 is: class myclass2

The types of i and j are the same

The types of i and f are not the same

ob1 and ob2 are of differing types

When a pointer of a polymorphic base class,it willautomatically return the type of the actual object being

pointed to, which may be a base-class object or anobject derived from that base.

Page 7: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 7/19

// An example that uses typeid on apolymorphic class hierarchy.

#include <iostream>

#include <typeinfo>

using namespace std;

class Mammal {

public:

virtual bool lays_eggs() { return false; }//Mammal is polymorphic

// ...

};

class Cat: public Mammal {

public:

// ...

};

class Platypus: public Mammal {public:

bool lays_eggs() { return true; }

// ...

};

int main()

{

Mammal *p, AnyMammal;

Cat cat;

Platypus platypus;p = &AnyMammal;

cout << "p is pointing to an object of type ";

cout << typeid(*p).name() << endl;

p = &cat;

cout << "p is pointing to an object of type ";

cout << typeid(*p).name() << endl;

p = &platypus;

cout << "p is pointing to an object of type ";

cout << typeid(*p).name() << endl;

return 0;

}

Output:

p is pointing to an object of type class Mammal

p is pointing to an object of type class Cat

p is pointing to an object of type class Platypus

Page 8: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 8/19

typeid is commonly applied to a

dereferenced pointer 

special exception has been created whenthe pointer being dereferenced is null.

In this case, typeid throws bad_typeid

Page 9: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 9/19

Other way of defining typeid, ± typeid(type-name)

void WhatMammal(Mammal &ob)

{cout << "ob is referencing an object of type ";

cout << typeid(ob).name() << endl;if(typeid(ob) == typeid(Cat))

cout << "Cats don't like water.\n";

}

Page 10: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 10/19

 A Simple Application of Run-Time Type ID

#include <iostream>using namespace std;class Mammal {public:virtual bool lays_eggs() { return false; }// Mammal is polymorphic// ...

};class Cat: public Mammal {public:// ...};class Platypus: public Mammal {

public:bool lays_eggs() { return true; }// ...};

class Dog: public Mammal {public:// ...};

// A factory for objects derived from Mammal.Mammal *factory(){switch(rand() % 3 ) {case 0: return new Dog;

case 1: return new Cat;case 2: return new Platypus;}return 0;

}

int main(){Mammal *ptr; // pointer to base classint i;int c=0, d=0, p=0;// generate and count objects

for(i=0; i<10; i++) {ptr = factory(); // generate an objectcout << "Object is " << typeid(*ptr).name();cout << endl;// count itif(typeid(*ptr) == typeid(Dog)) d++;

if(typeid(*ptr) == typeid(Cat)) c++;if(typeid(*ptr) == typeid(Platypus)) p++;}cout << endl;

cout << "Animals generated:\n";cout << " Dogs: " << d << endl;cout << " Cats: " << c << endl;cout << " Platypuses: " << p << endl;return 0;

}

Page 11: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 11/19

Output:

Object is class Platypus

Object is class Platypus

Object is class Cat

Object is class Cat

Object is class Platypus

Object is class CatObject is class Dog

Object is class Dog

Object is class Cat

Object is class Platypus

Animals generated:

Dogs: 2

Cats: 4

Platypuses: 4

Page 12: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 12/19

typeid in Template Classes

The type of an object is determined by what data

is used for its generic data when the object is

instantiated.

Two instances of the same template class usingdifferent data are therefore different types.

Page 13: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 13/19

// Using typeid with templates.

#include <iostream>

using namespace std;

template <class T> class myclass {

T a;public:

myclass(T i) { a = i; }

// ...

};

int main()

{

myclass<int> o1(10), o2(9);

myclass<double> o3(7.2);cout << "Type of o1 is ";

cout << typeid(o1).name() << endl;

cout << "Type of o2 is ";

cout << typeid(o2).name() << endl;

cout << "Type of o3 is ";

cout << typeid(o3).name() << endl;

cout << endl;

if(typeid(o1) == typeid(o2))cout << "o1 and o2 are the same type\n";

if(typeid(o1) == typeid(o3))

cout << "Error\n";

else

cout << "o1 and o3 are different types\n";

return 0;

}

Output:

Type of o1 is class myclass<int>

Type of o2 is class myclass<int>

Type of o3 is class myclass<double>

o1 and o2 are the same type

o1 and o3 are different types

Page 14: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 14/19

The Casting Operators

Page 15: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 15/19

C++ defines five casting operators ± the traditional-style cast inherited from C.

 ± dynamic_cast

 ± const_cast

 ± reinterpret_cast

 ± static_cast

Page 16: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 16/19

dynamic_cast

Performs a run-time cast that verifies the validityof a cast.

General form: ± dynamic_cast<target-type> (expr )

target-type -> target type of the cast

The target type must be a pointer or referencetype

expression being cast must evaluate to a pointer or reference

Page 17: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 17/19

purpose of dynamic_cast is to perform casts onpolymorphic types

dynamic_cast will succeed if the pointer (or reference)being cast is a pointer (or reference) to either an object

of the target type or an object derived from the targettype

If a dynamic_cast on reference types fails, a bad_castexception is thrown

Page 18: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 18/19

Base *bp, b_ob;

Derived *dp, d_ob;

bp = &d_ob; // base pointer points to Derived object

dp = dynamic_cast<Derived *> (bp); // cast to derivedpointer OK

if(dp) cout << "Cast OK";

the cast from the base pointer bp to the derived pointer dp works because bp is actually pointing to a Derived

object.

Page 19: (RTTI) & Casting Operator in C++

8/9/2019 (RTTI) & Casting Operator in C++

http://slidepdf.com/reader/full/rtti-casting-operator-in-c 19/19

bp = &b_ob; // base pointer points to Base object

dp = dynamic_cast<Derived *> (bp); // error 

if(!dp) cout << "Cast Fails";

Here the cast fails & displays Cast Fails