2

我有一个类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)但这似乎是一种骇人听闻的方法。或者您认为在这种情况下是否合理?

4

1 回答 1

1

您可以制作位置字段mutable,然后将逻辑只读方法标记为const.

如果您想在公共 API 中保留pushOffsetpopOffset方法,您应该引入私有版本const,并在您的readSomeDataFromKnownLocation方法中使用私有版本。

于 2012-12-06T13:08:46.877 回答