I have a doubt about about a line of the code wrote from my professor.
This is the full code.
The relevant function is
std::vector<AbstractButton*> removeUnchecked() {
std::vector<AbstractButton*> v;
CheckBox* p;
for(auto it = Buttons.begin(); it != Buttons.end(); ++it) {
p = const_cast<CheckBox*>(dynamic_cast<const CheckBox*>(*it));
if(p && !(p->isChecked())) {
v.push_back(p);
it = Buttons.erase(it); --it;
}
}
return v;
}
The class Gui has a std::list<const AbstractButton*> Buttons
and the function std::vector<AbstractButton*> removeUnchecked(){}
wants a vector as return type and we had to remove from the Gui every checkable buttons with the attribute checked == false
and put it in the returned vector.
The professor wrote CheckBox* p = const_cast<CheckBox*>(dynamic_cast<const CheckBox*>(*it));
performing a dynamic_cast first and then a const_cast
If I had written CheckBox* p = dynamic_cast<CheckBox*>(const_cast<AbstractButton*>(*it))
would it be the same thing? ( const_cast first and then dynamic_cast )
Both orders of the cast should be fine and do the same thing.
const_cast
will return a pointer pointing to the same object as before or a null pointer value if the argument is a null pointer value.
dynamic_cast
either returns a pointer pointing to a CheckBox
object or a null pointer value, without depending on the const
, except that it refuses to cast away a const
.
From looking at just the code you linked, it isn't clear to me though why the objects are stored as const
pointers in the first place.
const_cast
is one of the more dangerous casts. You must guarantee that the pointer which you const_cast
doesn't actually point to an object with const
type. If it does, then trying to modify the object through the new non- const
pointer will cause undefined behavior.
However in the code in your link there is an unrelated bug in the function. It uses std::list::erase
to remove the elements while iterating over the list. It correctly uses the return value of std::list::erase
as a new iterator to the next element.
But then, because the for
loop always executes it++
, in the loop body you it--
the return value from std::list::erase
to compensate.
However, if you just removed the first element of the list, then std::list::erase
will return a pointer to the new first element of the list, ie the new .begin()
iterator. Decrementing this pointer is not allowed and causes undefined behavior.
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.