static_cast is a C++ type casting operator used to perform explicit conversions between compatible types. It is commonly used for numeric conversions, user-defined conversions, inheritance-related casts, and conversions involving void*.
- Provides compile-time type checking and is safer than C-style casts.
- Supports conversions between related types, user-defined types, and void*.
- Cannot remove const qualifiers or perform low-level memory reinterpretation.
#include <iostream>
using namespace std;
// Driver code
int main()
{
float f = 3.5;
// Implicit type case
// float to int
int a = f;
cout << "The Value of a: " << a;
// using static_cast for float to int
int b = static_cast<int>(f);
cout << "\nThe Value of b: " << b;
}
Output
The Value of a: 3 The Value of b: 3
Explanation: The floating-point value 3.5 is explicitly converted to an integer. The fractional part is discarded during the conversion.
Syntax
static_cast<destination_type>(expression)
where:
- destination_type is the target type.
- expression is the value to be converted.
Uses of static_cast in C++
static_cast can be used in several scenarios:
1. Compile-Time Type Safety
Unlike C-style casts, static_cast rejects invalid conversions during compilation.
// C++ Program to demonstrate static_cast char* to int*
#include <iostream>
using namespace std;
// Driver code
int main()
{
int a = 10;
char c = 'a';
// Pass at compile time,
// may fail at run time
int* q = (int*)&c;
int* p = static_cast<int*>(&c);
return 0;
}
Output
error: invalid static_cast from type 'char*' to type 'int*'Explanation: static_cast does not allow conversion between unrelated pointer types, helping prevent unsafe type conversions.
2. User-Defined Conversions
static_cast can invoke constructors and conversion operators defined by a class.
#include <iostream>
#include <string>
using namespace std;
class Integer {
int x;
public:
Integer(int value = 0) : x(value) {}
operator string() {
return to_string(x);
}
};
int main()
{
Integer obj(10);
string str = static_cast<string>(obj);
cout << str;
}
Output
10
Explanation: The conversion operator operator string() is invoked to convert the object into a string.
3. static_cast with Inheritance
In inheritance hierarchies, static_cast can be used for conversions between related classes.
Upcasting: It converts a derived-class pointer to a base-class pointer.
#include <iostream>
using namespace std;
class Base {};
class Derived : public Base {};
int main()
{
Derived d;
Base* ptr = static_cast<Base*>(&d);
return 0;
}
Explanation: Since Derived publicly inherits from Base, the conversion is valid and performed safely at compile time.
Limitation with Private Inheritance
class Base {};
class Derived : private Base {};
int main()
{
Derived d;
Base* ptr = static_cast<Base*>(&d);
}
Compile-time Error
[Error] 'Base' is an inaccessible base of 'Derived'Explanation: static_cast respects access control rules. If the base class is inaccessible, the conversion is not allowed.
Note: For inheritance-based casts, the base class must be accessible, unambiguous, and non-virtual.
4. Converting To and From void*
static_cast allows conversions between object pointers and void*.
// C++ program to demonstrate static_cast to cast 'to and from' the void pointer
#include <iostream>
using namespace std;
// Driver code
int main()
{
int i = 10;
void* v = static_cast<void*>(&i);
int* ip = static_cast<int*>(v);
cout << *ip;
return 0;
}
Output
10
Explanation: The address of an integer is first converted to void* and then converted back to its original type.
Advantages of static_cast
The static_cast operator provides a safer and more explicit way to perform type conversions in C++, helping improve code readability and type safety.
- Provides stronger type checking than C-style casts.
- Makes conversions explicit and easier to understand.
- Detects invalid conversions at compile time.
- Supports user-defined conversions through constructors and conversion operators.
Limitations of static_cast
Despite being safer than C-style casts, static_cast has certain restrictions and cannot be used for all types of conversions.
- Cannot remove const or volatile qualifiers.
- Cannot safely cast between unrelated pointer types.
- Does not perform runtime type checking for downcasting.
- Cannot perform low-level memory reinterpretation like reinterpret_cast.