Static Cast in C++ – static_cast() Method

Filed Under: C++
Static Cast Cpp

In this article, we’ll take a look at using the Static Cast function in modern C++. We’ll also address some of the differences with respect to the other types of casts.

For many programmers with a C background, this may be a tricky topic.

There are different ways of performing implicit or explicit type conversions in C++, and with functions like static_cast(), dynamic_cast(), reinterpret_cast(), etc, it is very easy to get confused.


Understanding static_cast()

If you want to perform any type of conversion that is based on compile-time (static) inference, this is the way to go.

We can do the common C-type casting using static_cast(), such as converting an int to a float, and vice-versa. Similarly, we can also convert between pointers and references.

new_type value = static_cast <new_type> (expression);

This will return a value of type new_type, after casting expression.

For example, if you want to convert an arithmetic expression involving integers and floating points, to a float, you can do the following:

#include <iostream>

using namespace std;

int main() {
    int a = 5;
    float b = 20.5;
    
    float result = static_cast<float>(a + b);
    cout << result << endl;
    return 0;
}

Output

25.5

Indeed, our output has been statically cast to float, as shown above.

We can also convert pointers to/from types like void*.

#include <iostream>

template <class T>
bool isVoid(T *t) { return false;  } // normal case returns false 

template <>
bool isVoid(void *t) { return true; }  // but for void* returns true

using namespace std;

int main() {
    // Use a C-style cast to convert a string constant to a char*
    char* arr = (char*)"Hello from JournalDev";
    // Use static_cast() to convert to a void* pointer
    void* ptr = static_cast<void*>(arr);
    cout << "Is this a void* ptr? " << (isVoid(ptr) ? "Yes" : "No") << endl;
    // Convert back to char*
    cout << static_cast<char*>(ptr) << endl;
    return 0;
}

Output

Is this a void* ptr? Yes
Hello from JournalDev

We use a template function isVoid() to check if the pointer passed to it is void* or not. Observe that static_cast() is able to cast the pointers statically to any specific type.

static_cast() ensures that all the casts are performed at compile-time, so there is no runtime overhead with this function, unlike other casts like dynamic_cast().


Casting Through Inheritance

We can also perform casting through inheritance using static_cast(), provided the derived class is inherited publicly.

Consider the below code snippet.

#include <iostream>

using namespace std;

class BaseClass {
    public:
        int a, b;
        BaseClass(int val_a = 200, int val_b = 200) { 
        a = val_a; b = val_b; 
        }
        void print_obj() {
        cout<<"BaseClass Object: a = "<< a <<" , b = " <<b<< endl;
        }
        ~BaseClass() {
        }
};

// We can cast only if the inheritance is public
class DerivedClass : public BaseClass {
    public:
        int c;
        DerivedClass(int val_c = 100) { c = val_c; }
        void print_obj() {
            cout << "DerivedClass Object: a = " << a << " , b = " << b << " , c = " << c << endl; 
        }
        ~DerivedClass() {
        }
};

int main() {
    // We can only cast through inheritance if we use pointers
    // Otherwise, you need to construct the type conversion methods yourself
    BaseClass* base_obj = new BaseClass(20, 25);
    DerivedClass* derived_obj = new DerivedClass(10);

    base_obj->print_obj();
    derived_obj->print_obj();

    // Cast downwards - Can do this only if you don't use Virtual Inheritance
    DerivedClass* base_to_derived = static_cast<DerivedClass*>(base_obj);
    cout << "After casting BaseClass object to DerivedClass, ";
    base_to_derived->print_obj();

    // Can cast upwards - Redundant
    BaseClass* derived_to_base = static_cast<BaseClass*>(derived_obj);
    cout << "After casting DerivedClass object to BaseClass, ";
    derived_to_base->print_obj();

    // Free the pointers
    delete base_obj;
    delete derived_obj;

    return 0;
}

Here, we can perform pointer casts from the base class to the derived class using static_cast<DerivedClass*>(). You can only do this for pointers, and not for the objects themselves.

We can also do the reverse, but the cast is redundant, due to inheritance.

Output

BaseClass Object: a = 20 , b = 25
DerivedClass Object: a = 200 , b = 200 , c = 10
After casting BaseClass object to DerivedClass, DerivedClass Object: a = 20 , b = 25 , c = 0
After casting DerivedClass object to BaseClass, BaseClass Object: a = 200 , b = 200

Indeed, we’ve been able to cast successfully using static_cast<>(), and this is without the extra cost of doing it in runtime!

So, use static cast only if you’re doing casting between primitive types, or simple casting through inheritance. Otherwise, you’re better off using casts such as dynamic_cast<>().


Conclusion

In this article, we learned how we could use the static_cast() function in C++ to perform suitable type conversion during compile-time.

In future articles, we’ll look at similar concepts in modern C++, so stay tuned! Until then, do go through some of our C++ tutorials.


References


Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages