У меня есть класс, который переносит дескриптор файла:
class FileHandle
{
HANDLE hFile;
TCHAR name[256];
public:
LPCTSTR getName() const { /*(query system for name)*/ return this->name; }
};
Я придумал выбор дизайна:
Поскольку я буду часто запрашивать имя файла, чтобы минимизировать выделение кучи, которое могло бы произойти, если бы я возвратил std::wstring
(я неоднократно видел, что это является узким местом в моих программах), вместо этого я решил оставить name
поле внутри самого объекта и просто верните указатель на него, как показано.
Конечно, имя файла может со временем меняться, поэтому я не могу не запрашивать его каждый раз. Я могу только избежать перераспределения .
Конечно, раздел, говорящий (query system for name)
, будет не работать, как показано, потому что name
не mutable
.
С одной стороны, абонент не ожидает изменения имени файла. Но с другой стороны, это не , что означает const
в любом случае. Имя, безусловно, может измениться, просто вызывающая сторона не может его изменить. Так что, похоже, это не должно быть проблемой, но я не слишком уверен.
При каких обстоятельствах для меня будет хорошей идеей использовать mutable
здесь? Почему?
Примечание 1: Windows гарантирует , что имена файлов имеют длину не более 256 символов , поэтому здесь нет проблемы переполнения буфера.
Примечание 2: Класс предназначен только для однопоточного использования. Меня не беспокоит одновременных модификаций, только модификации между заявлениями.
Почему const
не подразумевает неизменность:
Это должно быть само за себя:
FileHandle file = ...;
const FileHandle &fileConst(file);
LPCTSTR name1 = fileConst.getName();
file.setName(_T("new name"));
LPCTSTR name2 = fileConst.getName();
Теперь name1
и name2
не равны. Так что не только может изменить имя файла довольно легко, но name1
сам также может измениться - даже если они оба const
. Нет правила, гласящего, что const
участники не могут измениться, просто они не могут быть изменены через const
ссылку .