Const pointer argument to a method which delegates to removeAll()
Consider a method like this:
void Parent::removeChild(Child *child)
{
children.removeAll(child);
}
In this case, since child is never modified itself, one could make it a const pointer. But since children is of the type QList, the removeAll() takes a const reference to a non-const pointer.
What's the recommended way to handle this? Skip the constness of the method argument or to const_cast the const poi开发者_StackOverflow中文版nter to fit the removeAll() method?
Tricky one. You should have added some more code, but from the docs I assume that you have a QList<Child*>
and cannot change it to a QList<const Child*>
because you need to access the actual objects in a non-const manner.
Since all the removeAll()
function does is to remove the entry in the list and it in no way modifies the pointed-to Child (how could it, it doesn't know anything about the Child class) it would be safe here to use a const_cast
.
If what you want is to say that changing the children list is not a change of a Parent instance, then just make the children list mutable
.
However, make sure that it's really the semantic you want for you Parent class. If children are not part of the state of Parent (in your system's semantic), then it should be fine. If it is part of the Parent instance state, then you should keep a non-const member function.
The mutable keyword is there for thoses exceptional cases where a member of a class shouldn't be taken as the state of an instance, just additional informations. If it's your case then use it.
Otherwise let your member function be non-const as it modifiesa Parent member.
It looks like QList
is designed to be used on non-pointers. They define a lot of the interface that is const as const T&
which would work great if your QList
was on Child
, not Child*
.
It will work on pointers just fine, but it can't declare the constness right for them. I don't recommend changing your QList to Child unless it's cheap to copy, you have all the right semantics for copy ctor, dtor, op=, op==, etc and you don't mind having copies in the list rather than the objects you pass in. You can see how with int
or strings, that it would work as expected (removeAll would be const correct).
If const correctness is important to you, then use a const_cast. Then declare a const ref and pass that in.
void Parent::removeChild(const Child *child)
{
QList<Child*>::const_reference constRefToChild = const_cast<Child *> child;
children.removeAll(constRefToChild);
}
The point of this is that if removeAll is ever changed to not take a const, you get a compiler error. Then you'd know that removeAll isn't preserving constness of the argument.
精彩评论