Reputation: 497
I've read quite a few discussions that const_cast in C++ is considered wrong and dangerous and should not be used for anything other than backward compatibility with C code. And I generally agree.
However recently I came across the following use case and it made me wonder.
I have some model object, owned by a controller, that is generally non-const. I pass it to a view that should not be able to modify the model object, so it would be logical to declare the object as a const parameter when passed to the view. However the view also makes delegate callbacks to the controller, passing the model object as a parameter (e.g. the user clicked this object). The callback parameter also must be const. In the callback method, the controller wants to make a change to the model, but the model is const so it can't do it.
The two solutions:
Thoughts?
Upvotes: 1
Views: 121
Reputation: 275350
There are two ways to deal with const
.
Things are const
if this code won't directly change them.
Things are const
if this code won't change them.
In this case, the view won't directly change the object. But you want it to indirectly change the object.
Under (2), this means the object isn't const
. The view can change the object, if indirectly. It can cause the object to be changed. Saying it is const
implies that the views interaction with the object is purely "reading state", not changing the state -- but clicking on the "delete" button of the object and making it delete is a mutating operation.
Under (1), your reference should be const
, because you aren't yourself modifying it. Someone else is, under authority granted by their right to do it.
This is one conflict. And (1) is an acceptable way to use const
. But when using (1) you should have an alternative route to the object as non-const
.
We can see this under vector.erase
. It (now) takes const_iterator
s. Even though those iterators themselves are not permitted to modify the vector, the non-const
ness of *this
provides an alternative access path that permits modification.
In your case, the controller owns the object, so should have a non-const
access path to that object. That is the path you should use to do non-const
modification of the object.
When the view makes a delegate callback, it might pass an identifier instead of an object -- or, the controller might extract the identifier from the object somehow, and look it back up in its own list of objects.
Upvotes: 5
Reputation: 29023
This is not a good case for const_cast
. If the view
accepts the model
as a const
then it can be given a truly const
instance of model
. It would then be incorrect to try to pass that instance to the controller. If the reference to the model
given to the view
can be used to modify the model
, then it must not be const
.
Upvotes: 2