Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it acceptable to cast away constness in a move constructor?

Suppose I have a class Foo that has a private pointer to a Bar:

class Foo
{
private:
  Bar * bar;

public:
  Foo () : bar (new Bar ())
  {}

  ~Foo ()
  {
    delete bar;
  }
};

If the pointer bar should never be reassigned to a different instance, then it makes sense to make the pointer itself const in order to stop me (or a maintainer) from doing so in the future:

private:
  Bar * const bar;

I like doing this wherever the opportunity arises.

If I then wanted to write a move constructor, it would look something like this:

Foo (Foo && f) :
   bar (f.bar)
{
  f.bar = NULL;  // uh oh; f.bar is const.
}

I can "make the error go away" either by casting away the constness of f.bar or by not making it const in the first place. Neither of which are things I want to do. I'd rather not remove the const completely because it's there for a reason. On the other hand, casting away constness rings alarm bells for me and is something I never usually do. My question is: is it considered acceptable practice to cast away constness within a move constructor like this? Is there a better way that I haven't considered?

I don't think my question is the same as this one: Use const_cast to implement the move constructor

like image 733
peterpi Avatar asked Oct 24 '14 09:10

peterpi


People also ask

What is the use of move constructor in c++?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying.

Is move constructor automatically generated?

No move constructor is automatically generated.

When move constructor is not generated?

The move constructor is not generated because you declared a copy constructor. Remove the private copy constructor and copy assignment. Adding a non-copyable member (like a unique_ptr ) already prevents generation of the copy special members, so there's no need to prevent them manually, anyway.

Why const_ cast is used?

const_cast is one of the type casting operators. It is used to change the constant value of any object or we can say it is used to remove the constant nature of any object. const_cast can be used in programs that have any object with some constant value which need to be changed occasionally at some point.


1 Answers

If you will have to change the pointer in some case (even if it's only a single case), then it probably shouldn't be const.

However, even putting this thought aside, using const_cast to remove constness from an object, and then using the result of the cast invokes undefined behavior. It is only safe to const_cast a variable that was originally not const.

like image 114
SingerOfTheFall Avatar answered Nov 06 '22 15:11

SingerOfTheFall