C++ Tutorial
Class and Object
Reference
Inheritance and Derivation
Polymorphism and Virtual Functions
Operator Overloading
Template
Exception
Object Oriented Advanced
Input/Output Stream
File Operations
In this tutorial, we will learn about the typeid
operator in C++. The typeid
operator is part of the C++ Run-Time Type Information (RTTI) system and allows you to obtain information about a type at runtime. You can use the typeid
operator to compare the types of two objects, get the name of a type, or perform type-specific operations based on the runtime type of an object.
typeid
:Here's a simple example demonstrating the use of the typeid
operator:
#include <iostream> #include <typeinfo> class Base { public: virtual ~Base() {} }; class Derived : public Base {}; int main() { Base* basePtr = new Derived(); if (typeid(*basePtr) == typeid(Derived)) { std::cout << "The object is of type Derived." << std::endl; } else { std::cout << "The object is not of type Derived." << std::endl; } delete basePtr; return 0; }
In this example, we define a Base
class and a Derived
class that inherits from Base
. In the main()
function, we create a Base
pointer pointing to a Derived
object. We use the typeid
operator to compare the runtime type of the object pointed to by basePtr
with the type Derived
. The comparison is true because the object is actually of type Derived
.
typeid
with the name()
function:The typeid
operator returns a reference to a std::type_info
object, which contains information about the type. You can use the name()
function to get a human-readable (but compiler-specific) name for a type:
#include <iostream> #include <typeinfo> int main() { int integer = 5; double floating = 3.14; std::cout << "Type of integer: " << typeid(integer).name() << std::endl; // Output: Type of integer: int std::cout << "Type of floating: " << typeid(floating).name() << std::endl; // Output: Type of floating: double return 0; }
Keep in mind that the names returned by the name()
function are compiler-specific and may not be the same across different compilers.
typeid
with polymorphism:When using typeid
on a base class object with virtual functions, it will provide the actual type of the object at runtime, which is useful when working with polymorphic classes:
#include <iostream> #include <typeinfo> class Base { public: virtual ~Base() {} }; class Derived1 : public Base {}; class Derived2 : public Base {}; void printType(Base* basePtr) { std::cout << "Type of object: " << typeid(*basePtr).name() << std::endl; } int main() { Derived1 d1; Derived2 d2; printType(&d1); // Output: Type of object: Derived1 printType(&d2); // Output: Type of object: Derived2 return 0; }
In this example, we define a Base
class and two derived classes, Derived1
and Derived2
. We use a printType
function that takes a Base
pointer and prints the runtime type of the object pointed to by the pointer.
How to use typeid
for type identification in C++:
#include <iostream> #include <typeinfo> int main() { int intValue = 42; const std::type_info& typeInfo = typeid(intValue); std::cout << "Type: " << typeInfo.name() << std::endl; return 0; }
typeid
operator returns type information about an expression.typeid
vs dynamic_cast
in C++:
#include <iostream> #include <typeinfo> class Base { public: virtual ~Base() {} }; class Derived : public Base {}; int main() { Base* basePtr = new Derived(); // Using typeid for type identification const std::type_info& typeInfo = typeid(*basePtr); if (typeInfo == typeid(Derived)) { std::cout << "Object is of type Derived" << std::endl; } else { std::cout << "Object is not of type Derived" << std::endl; } delete basePtr; return 0; }
typeid
is used for querying type information, while dynamic_cast
is used for safe downcasting in polymorphic classes.Using typeid
with polymorphism in C++:
#include <iostream> #include <typeinfo> class Shape { public: virtual ~Shape() {} }; class Circle : public Shape {}; int main() { Circle circle; Shape* shapePtr = &circle; // Using typeid with polymorphism if (typeid(*shapePtr) == typeid(Circle)) { std::cout << "Shape is a Circle" << std::endl; } else { std::cout << "Shape is not a Circle" << std::endl; } return 0; }
typeid
can be used with polymorphic classes to identify the actual type of an object.Type information for user-defined classes with typeid
in C++:
#include <iostream> #include <typeinfo> class MyClass { // Class definition }; int main() { MyClass myObject; const std::type_info& typeInfo = typeid(myObject); std::cout << "Type: " << typeInfo.name() << std::endl; return 0; }
typeid
can be used with user-defined classes to obtain type information.typeid
and exception handling in C++:
#include <iostream> #include <typeinfo> class MyException : public std::exception { public: const char* what() const noexcept override { return "Custom exception"; } }; int main() { try { throw MyException(); } catch (const std::exception& e) { // Using typeid in exception handling if (typeid(e) == typeid(MyException)) { std::cout << "Caught MyException" << std::endl; } else { std::cout << "Caught a different exception" << std::endl; } } return 0; }
typeid
can be used in exception handling to identify the type of the caught exception.typeid
and template metaprogramming in C++:
#include <iostream> #include <typeinfo> template <typename T> void printType() { const std::type_info& typeInfo = typeid(T); std::cout << "Type: " << typeInfo.name() << std::endl; } int main() { printType<int>(); printType<double>(); printType<std::string>(); return 0; }
typeid
can be used in template metaprogramming to obtain type information.typeid
and type traits in C++:
#include <iostream> #include <type_traits> #include <typeinfo> template <typename T> void printTypeIfInteger() { if (std::is_integral<T>::value) { const std::type_info& typeInfo = typeid(T); std::cout << "Type is an integer: " << typeInfo.name() << std::endl; } else { std::cout << "Type is not an integer" << std::endl; } } int main() { printTypeIfInteger<int>(); printTypeIfInteger<double>(); return 0; }
typeid
can be used in combination with type traits to perform type-specific operations.