When a function doesn't modify an object argument, I always make it ask for a constant reference even if the referenced object isn't really constant. Is this wrong?
For a wrapper class, I'd like to write this:
template<class B>
class Wrapper{
private:
B* base_;
public:
Wrapper(const B& b) { base_ = const_cast<B*>(&b); }
void ModifyBase();
};
The constructor doesn't modify the base so it asks for a constant reference.
The wrapper have some methods who will need to modify the base so it needs to store a non-constant pointer (thus the conversion).
I feel my solution is not the best.
Is there a better way to do this?
Is there any accepted convention?
When you choose your parameter to be a const
reference, you're telling the user "You can trust that if you pass me an object, it will not get modified [through this reference]†." You should do that as often as possible, because the user can understand more about what your function will and won't do just from looking at the types. Also, passing around mutable references can lead to code that is difficult to reason about.
However, in your question, your const
is not telling the truth. It is casting away the const
ness and storing a non-const
pointer - this means the object may very well get modified. You lied to the user! It doesn't matter that the constructor itself does nothing to do the object. It allows it to be modified by other member functions. This is bad behaviour. Your constructor should not take a const
reference.
Not only that, but your current implementation allows undefined behaviour. Even if an object that is originally declared as const
is given to your Wrapper
, it doesn't care. It casts away it's const
ness and allows the other member functions to modify it. Modifying an object that was originally const
is undefined behaviour.
† See 6502's comment