In C++, dynamic_cast is a cast operator that converts data from one type to another type at runtime. It is mainly used in inherited class hierarchies for safely casting the base class pointer or reference to derived class (called downcasting). To work with dynamic_cast, there must be one virtual function in the base class.
Syntax
C++
dynamic_cast <new_type>(expression)
If the object being pointed to is of the correct type (or a type convertible to it), the cast succeeds. If the cast is invalid, the pointer is set to nullptr or it is a reference, then it throws std::bad_cast exception.
Note: A Dynamic_cast has runtime overhead because it checks object types at run time using “Run-Time Type Information“. If there is a surety we will never cast to wrong object then always avoid dynamic_cast and use static_cast.
Examples of Dynamic Cast
The below examples demonstrate how to use the dynamic cast in C++:
Downcasting using dynamic_cast
C++
#include <iostream>
using namespace std;
// Base Class declaration
class Base {
public:
virtual void print() {
cout << "Base" << endl;
}
};
// Derived1 class declaration
class Derived1 : public Base {
public:
void print() {
cout << "Derived1" << endl;
}
};
int main() {
Derived1 d1;
// Base class pointer holding
// Derived1 Class object
Base* bp = &d1;
// Dynamic_casting
Derived1* dp2 = dynamic_cast<Derived1*>(bp);
if (dp2 == nullptr)
cout << "Casting Failed" << endl;
else
cout << "Casting Successful" << endl;
return 0;
}
In this program, there is one base class and two derived classes (Derived1, Derived2), here the base class pointer hold derived class 1 object (d1). At the time of dynamic_casting base class, the pointer held the Derived1 object and assigning it to derived class 1, assigned valid dynamic_casting.
Downcasting a Non-Polymorphic Type
As we mention above for dynamic casting there must be one Virtual function. Suppose If we do not use the virtual function, then what is the result? In that case, it generates an error message “Source type is not polymorphic”.
C++
#include <iostream>
using namespace std;
// Non-polymorphic base class
class Base {
public:
void print() {
cout << "Base" << endl;
}
};
class Derived1 : public Base {
public:
void print() {
cout << "Derived1" << endl;
}
};
int main() {
Derived1 d1;
Base* bp = &d1;
// Dynamic_casting
Derived1* dp2 = dynamic_cast<Derived1*>(bp);
if (dp2 == nullptr)
cout << "Casting Failed" << endl;
else
cout << "Casting Successful" << endl;
return 0;
}
Output
main.cpp: In function ‘int main()’:
main.cpp:24:21: error: cannot ‘dynamic_cast’ ‘bp’ (of type ‘class Base*’) to type ‘class Derived1*’ (source type is not polymorphic)
24 | Derived1* dp2 = dynamic_cast<Derived1*>(bp);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
Virtual functions include run-time type information and there is no virtual function in the base class. So, this code generates an error.
Trying Invalid Downcasting
Now, If the cast fails and new_type is a pointer type, it returns a null pointer of that type.
C++
#include <iostream>
using namespace std;
class Base {
virtual void print() {
cout << "Base" << endl;
}
};
// Derived1 class declaration
class Derived1 : public Base {
void print() {
cout << "Derived1" << endl;
}
};
// Derived2 class declaration
class Derived2 : public Base {
void print() {
cout << "Derived2" << endl;
}
};
int main() {
Derived1 d1;
Base* bp = &d1;
// Dynamic Casting
Derived2* dp2 = dynamic_cast<Derived2*>(bp);
if (dp2 == nullptr)
cout << "Casting Failed" << endl;
else
cout << "Casting Successful" << endl;
return 0;
}
Explanation: In this program, at the time of dynamic_casting base class pointer holding the Derived1 object and assigning it to derived class 2, which is not valid dynamic_casting. So, it returns a null pointer of that type in the result.
Downcasting a Reference
Now take one more case of dynamic_cast. If the cast fails and new_type is a reference type, it throws an exception that matches a handler of type std::bad_cast and gives a warning: dynamic_cast of “Derived d1” to “class Derived2&” can never succeed.
C++
// C++ Program demonstrate if the cast
// fails and new_type is a reference
// type it throws an exception
#include <exception>
#include <iostream>
using namespace std;
class Base {
virtual void print() {
cout << "Base" << endl;
}
};
class Derived1 : public Base {
void print() {
cout << "Derived1" << endl;
}
};
class Derived2 : public Base {
void print() {
cout << "Derived2" << endl;
}
};
int main() {
Derived1 d1;
Base* bp = dynamic_cast<Base*>(&d1);
// Type casting
Derived1* dp2 = dynamic_cast<Derived1*>(bp);
// Exception handling block
try {
Derived2& r1 = dynamic_cast<Derived2&>(d1);
}
catch (std::exception& e) {
cout << e.what() << endl;
}
return 0;
}
Output
main.cpp:31:15: warning: unused variable ‘dp2’ [-Wunused-variable]
31 | Derived1* dp2 = dynamic_cast<Derived1*>(bp);
| ^~~
std::bad_cast
Similar Reads
Dynamic Binding in C++
Dynamic binding in C++ is a practice of connecting the function calls with the function definitions by avoiding the issues with static binding, which occurred at build time. Because dynamic binding is flexible, it avoids the drawbacks of static binding, which connected the function call and definiti
3 min read
static_cast in C++
A Cast operator is a unary operator which forces one data type to be converted into another data type. C++ supports 4 types of casting: Static CastDynamic CastConst CastReinterpret CastThis article focuses on discussing the static_cast in detail. Static CastThis is the simplest type of cast that can
5 min read
Dynamic Constructor in C++ with Examples
When allocation of memory is done dynamically using dynamic memory allocator new in a constructor, it is known as dynamic constructor. By using this, we can dynamically initialize the objects. Example 1: C/C++ Code #include <iostream> using namespace std; class geeks { const char* p; public: /
3 min read
Constructors in C++
In C++, constructor is a special method that is invoked automatically at the time an object of a class is created. It is used to initialize the data members of new objects. The constructor in C++ has the same name as the class or structure. Example: [GFGTABS] C++ #include <iostream> using name
6 min read
Casting Operators in C++
The casting operators is the modern C++ solution for converting one type of data safely to another type. This process is called typecasting where the type of the data is changed to another type either implicitly (by the compiler) or explicitly (by the programmer). Let's take a look at an example: [G
5 min read
copysign() function in C++
copysign(x, y) function returns the value with a magnitude of x and the sign of y. Examples: Input : copysign(6, -2) Output : -6 Input : copysign(-6, 2) Output : 6 Syntax: copysign(x, y); Parameters: x : Value with the magnitude y : Value with the sign Returns : Returns the value with a magnitude of
1 min read
C++ boost::dynamic_bitset Class with Examples
The boost has more than 150 libraries in it, where a couple of most frequently used libraries were already included in C++ standard library. The dynamic_bitset is a powerful library used for bit manipulation. The dynamic_bitset class is used to represent a set of bits in either 0(reset) or 1(set) fo
15 min read
Object Slicing in C++
When a derived class object is assigned to a base class object in C++, the derived class object's extra attributes are sliced off (not considered) to generate the base class object; and this whole process is termed object slicing. In simple words, when extra components of a derived class are sliced
4 min read
Boost.Lexical_Cast in C++
Boost.LexicalCast which is defined in the Library "boost/lexical_cast.hpp" provides a cast operator, boost::lexical_cast, that can convert numbers from strings to numeric types like int or double and vice versa. boost::lexical_cast is an alternative to functions like std::stoi(), std::stod(), and st
2 min read
typeinfo::bad_cast in C++ with Examples
Standard C++ contains several built-in exception classes. typeinfo::bad_cast is one of them. This is an exception thrown on failure to dynamic cast. Below is the syntax for the same: Header File: <typeinfo> Syntax: class bad_cast; Note: To make use of std::bad_cast, one should set up the appro
2 min read