Sunday, 21 April 2019

C++: When to Cast Away Const

There's a rule, a very good rule, a brilliant rule, almost a law to not cast away const in C++.  There are legitimate reasons for this, and greater minds than myself have invented and enforced said coding standard.

Unfortunately, this doesn't mean there are not cases where you can use this technique, lets take a look.

So, modern C++ casts should always be used.  These are static_cast, reinterpret_cast, the dreaded dynamic_cast and as we're going to look at const_cast.  Where would I use this?  Well, in concert with good parameter conventions, we always want to communicate to the outside world what we'll use a parameter for...

class Foo
{
private:
    int* memory;


public:
    Foo(int* ourMemory)
        :
        memory(ourMemory)
    {
    }

};

We're assigning our memory to the class, but this constructor is communicating something back to the caller, it intimates that the pointer could perhaps, maybe, be changed as we pass it without the constant prefix.  A caller could then assume they must check whether the pointer has changed, become nullptr or whatever else.  That's assuming our API users are good people, which we all knows they are!

But, we don't change the pointer, we just take it into our member variable pointer.

We therefore have a dichotomy, the class may change the pointer along the way, but the actual constructor does not, this is a design decision, so assuming we communicate this back, I just want to make it clear the constructor does not change the pointer.

class Foo
{
private:
    int* memory;


public:
    Foo(const int* ourMemory)
        :
        memory(ourMemory)
    {
    }

};

Unfortunately you now get a compile error that "int*" can't be cast to "const int*".  So we need to cast-away the const in our constructor, like this:

class Foo
{
private:
    int* memory;


public:
    Foo(const int* ourMemory)
        :
        memory(const_cast<int*>(ourMemory))
    {
    }

};

This is, pretty much, the only use case I can find in my own coding standards for casting away const.