У меня есть класс FileSystem, и я хочу хочу сделать, чтобы с итераторов можно было выполнять некоторые методы самого класса. Для этого в итератор добавил указатель на класс чтобы методы вызванные с итератора были примерно такими:
int FileSystem::iterator::make_dir(const std::string& name){
return указатель_на_FileSystem->make_dir(name,указатель_на_Dir );
}
метод в классе FileSystem:
int FileSystem::make_dir(const std::string& name, Dir* & cur_dir);
Создавать итератор хотел так
iterator(this,указатель_на_Dir);
Проблема в том, что this - константный, соответственно в итераторе можно создавать можно только константные указатели на FileSystem и выполнять только константные методы.
Вопрос заключается в том, стоит ли делать
const_cast<...>(this)
и насколько это плохо. Возможно стоит как-то пересмотреть архитектуру или использовать что-то другое?
Ответ
this может иметь несколько разных типов:
T * const при вызове функции-члена на константном объекте (т.е. нельзя изменять как сам this, так и то, на что он указывает);
T * при вызове на изменяемом объекте (по прежнему нельзя изменять this, но можно изменять объект, на который он указывает);
ещё пара вариантов с volatile (в данном случае, не рассматриваем).
Если создание вашего итератора происходит в константной функции, то и this имеет соответствующий тип. Таким образом, как минимум следует создавать итератор там, где объект, указываемый this может изменяться. Более того, не обязательно создавать итератор именно из функции-члена.
Преобразования const_cast, сбрасывающие константность у действительно константных объектов приводят к неопределённому поведению. Поэтому тут надо быть крайне осторожным.
В качестве возможного подхода предлагаю рассмотреть ситуацию с итераторами для стандартных контейнеров. Они имеют как const-версию, так и обычную. Т.е. существуют два отдельных класса итераторов. Надеюсь, такое объяснение позволит решить Вашу проблему.
Комментариев нет:
Отправить комментарий