У меня есть класс Reader
который обеспечивает доступ к двоичному файлу для выполнения операций чтения с ним.
Этот файл содержит несколько списков смещений в одном файле, где находятся данные. Это означает, что, чтобы добраться до определенных сегментов данных, нужно прочитать смещение с некоторой позиции, затем перейти к этому смещению, снова прочитать смещение, перейти туда и т. Д., Пока, наконец, вы не достигнете фактических данных.
Класс поддерживает позицию чтения, которая корректируется каждый раз, когда вы вызываете такой метод, как
// reads 4 bytes and advances the position by 4 bytes
uint32 Reader::readOffset() { /* */ }
или же
// moves the position to offset
void Reader::jumpTo(uint32 offset) { /* */ }
Эти методы, очевидно, не могут быть const
как они перемещают позицию чтения.
Для удобной навигации между несколькими уровнями файла класс предоставляет стек, в котором можно сдвигать и выталкивать смещения по мере необходимости:
uint32 someOffset = reader.readOffset();
reader.pushOffset(); // remember position
reader.jumpTo(someOffset); // do something on another position
reader.popOffset(); // go back to where we were before
Эти методы push / pop не могут быть const
также, потому что они изменяют стек смещения.
Проблема теперь в удобных методах, которые должны извлекать данные из внутренней известной позиции в файле. Они должны работать независимо от текущей позиции чтения и не должны ее трогать. По замыслу они должны быть const
, но это не работает:
uint32 Reader::readSomeDataFromKnownLocation() const
{
pushOffset();
jumpTo(1234ul);
uint32 data = readData();
popOffset();
return data;
}
я делать знаю, что этот метод оставит объект в том же состоянии, в котором он был до вызова, но все же я не могу сделать это const
потому что каждый метод, который я использую в нем, неconst
,
Итак, мой вопрос заключается в том, каков наилучший подход, когда необходимо временно изменить состояние объекта в рамках «побочного дизайна» const
метод?
Я думал о const_cast<Reader*>(this)
но это похоже на хакерский подход. Или вы думаете, это оправдано в этом сценарии?
Вы можете сделать поле позиции mutable
а затем пометьте свои логически доступные только для чтения методы как const
,
Если вы хотите сохранить pushOffset
а также popOffset
методы в публичном API, вы должны представить частные версии, которые const
и использовать частные из вашего readSomeDataFromKnownLocation
метод.
Других решений пока нет …