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 C++ casting operators: static_cast
, dynamic_cast
, const_cast
, and reinterpret_cast
. These casting operators allow you to convert one type to another, providing control over the conversion process, and making your code more expressive and self-documenting.
static_cast
:static_cast
is the most commonly used casting operator. It performs a simple and well-defined set of conversions, such as converting between basic data types or related user-defined types (e.g., between base and derived classes). It can also be used for implicit conversions.
int main() { double num = 3.14; int integer = static_cast<int>(num); // Converts double to int, truncating the decimal part std::cout << "Integer: " << integer << std::endl; // Output: Integer: 3 return 0; }
dynamic_cast
:dynamic_cast
is used for safely converting pointers or references of base class types to derived class types in a polymorphic class hierarchy. It checks the type at runtime and returns a null pointer (for pointers) or throws a std::bad_cast
exception (for references) if the conversion is not valid.
class Base { public: virtual ~Base() {} }; class Derived : public Base {}; int main() { Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // Successful cast if (derivedPtr != nullptr) { std::cout << "Casting succeeded." << std::endl; } else { std::cout << "Casting failed." << std::endl; } delete basePtr; return 0; }
const_cast
:const_cast
is used to add or remove the const
, volatile
, or const volatile
qualifier from a variable. It is often used to call non-const functions on const objects.
void nonConstFunc(int& num) { num *= 2; } int main() { const int num = 5; // nonConstFunc(num); // This would result in a compilation error int& nonConstNum = const_cast<int&>(num); nonConstFunc(nonConstNum); std::cout << "Modified number: " << nonConstNum << std::endl; // Output: Modified number: 10 return 0; }
reinterpret_cast
:reinterpret_cast
is used to convert a pointer or reference to any other pointer or reference type. It simply treats the bits of the source value as the bits of the target type. This is the most dangerous cast because it can lead to unpredictable results if the source and target types are not compatible.
int main() { int num = 42; int* intPtr = # char* charPtr = reinterpret_cast<char*>(intPtr); std::cout << "Character value: " << *charPtr << std::endl; return 0; }
That's it for our C++ casting operators tutorial. Understanding these casting operators is crucial for writing clean and efficient code, as they allow you to perform type conversions with precision and control. Each casting operator has its own set of use cases and limitations, so use them judiciously to ensure that your code remains safe and maintainable.
How to use static_cast
in C++:
#include <iostream> int main() { double doubleValue = 3.14; int intValue = static_cast<int>(doubleValue); // Using static_cast for type conversion std::cout << "Double value: " << doubleValue << std::endl; std::cout << "Int value: " << intValue << std::endl; return 0; }
static_cast
is used for compile-time type conversion.Dynamic type casting with dynamic_cast
in C++:
#include <iostream> #include <typeinfo> class Base { public: virtual ~Base() {} }; class Derived : public Base {}; int main() { Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // Using dynamic_cast for runtime type checking if (derivedPtr) { std::cout << "Dynamic cast successful" << std::endl; } else { std::cout << "Dynamic cast failed" << std::endl; } delete basePtr; return 0; }
dynamic_cast
is used for dynamic (runtime) type checking.When to use const_cast
in C++:
#include <iostream> int main() { const int constValue = 42; int& nonConstRef = const_cast<int&>(constValue); // Using const_cast to remove const qualifier nonConstRef = 99; std::cout << "Modified value through const_cast: " << constValue << std::endl; return 0; }
const_cast
is used to add or remove the const
qualifier.reinterpret_cast
in C++ for low-level type conversions:
#include <iostream> int main() { int intValue = 42; double* doublePtr = reinterpret_cast<double*>(&intValue); // Using reinterpret_cast for low-level type conversion std::cout << "Value through reinterpret_cast: " << *doublePtr << std::endl; return 0; }
reinterpret_cast
is used for low-level type conversions, often between pointers.Type conversion operators and polymorphism in C++:
#include <iostream> class Shape { public: virtual double area() const = 0; }; class Circle : public Shape { private: double radius; public: Circle(double radius) : radius(radius) {} double area() const override { return 3.14 * radius * radius; } }; int main() { Circle circle(5.0); Shape* shapePtr = &circle; // Using dynamic_cast to convert from base class pointer to derived class pointer Circle* circlePtr = dynamic_cast<Circle*>(shapePtr); if (circlePtr) { std::cout << "Area of the circle: " << circlePtr->area() << std::endl; } return 0; }
Type conversion operators for user-defined classes in C++:
#include <iostream> class Distance { private: double meters; public: Distance(double meters) : meters(meters) {} operator double() const { return meters; } }; int main() { Distance distance(100.0); double value = distance; // Using user-defined type conversion operator std::cout << "Distance in meters: " << value << std::endl; return 0; }