Reputation: 575
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
Upvotes: 8
Views: 500
Reputation: 41331
If possible, use unique_ptr
instead:
std::unique_ptr<Bar> bar;
Foo(Foo&& f) : bar(std::move(f.bar)){}
// or maybe you won't even have to declare move constructor
This way not only you'll get more safety and comfort, but also you won't accidentaly rewrite it with =
, you'll have to call .reset()
so you'll think twice before doing it (which is your aim, I suppose).
Upvotes: 3
Reputation: 29976
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.
Upvotes: 6
Reputation: 49261
You are basically contradicting yourself.
You are saying "I don't want to change it in any circumstance", and the you're saying "I want to change it when i move an object".
So, if there is a scenario where it needs to be changed, then it's not a const
, and you can feel comfortable removing it.
If you are determined that you want it const
, you can add another boolean value that determines ownership (if you need to handle resource life-time). So the pointed object may be released only when a destructor that owns the object is called.
Upvotes: 4