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
It doesn't really matter that the ctor
won't alter the object in the ctor
, what happens after the ctor
is done is why you need a non- const
object pointer to B
. So it has to do with ownership and lifetime of the B
object passed in: if you want to take ownership (via the &
reference, then the object must be non- const
because it can be altered. If you want to simply copy the B
object passed in, then don't use a refernce, pass by value and store a pointer to the copy.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.