I have a class that wraps a file handle:
class FileHandle
{
HANDLE hFile;
TCHAR name[256];
public:
LPCTSTR getName() const { /*(query system for name)*/ return this->name; }
};
I have come up with a design choice:
Since I will be querying the file name often, in order to minimize heap allocations which would happen if I returned std::wstring
(I have repeatedly seen that this is a bottleneck in my programs), I have instead decided to keep a name
field inside the object itself, and just return a pointer to it as shown.
Of course, the name of the file can change over time, so I can't avoid querying it every time. I can only avoid the reallocation.
Of course, the section saying (query system for name)
would not work as shown because name
isn't mutable
.
On the one hand, the caller doesn't expect the file name to change. But on the other hand, that's not what const
means, anyway. The name can certainly change, it's just that the caller can't modify it. So it doesn't look like it should be a problem, but I'm not too sure.
Under what circumstances would it be a good idea for me to use mutable
here? Why?
Note 1: Windows guarantees that file names are at most 256 characters long, so there's no buffer overflow issue to consider here.
Note 2: The class is only designed for single-threaded use. I'm not worried about concurrent modifications, only modifications in between statements.
Why const
doesn't imply immutability:
This should be self-explanatory:
FileHandle file = ...;
const FileHandle &fileConst(file);
LPCTSTR name1 = fileConst.getName();
file.setName(_T("new name"));
LPCTSTR name2 = fileConst.getName();
Now name1
and name2
aren't equal. So not only can the file name change quite easily, but name1
itself can also change -- even though they're both const
. There's no rule saying that const
members can't change, just that they can't be changed through the const
reference.