|
The solution is simple: take advantage of C++(www.cppentry.com)’s const-related wiggle room known as mutable. mutable frees non-static data members from the constraints of bitwise constness: - class CTextBlock {
- public:
... std::size_t length() const; private: char *pText; mutable std::size_t textLength; mutable bool lengthIsValid; }; std::size_t CTextBlock::length() const { if (!lengthIsValid) { textLength = std::strlen(pText); lengthIsValid = true; } return textLength; }
Avoiding Duplication in const and Non-const Member Functions
mutable is a nice solution to the bitwise-constness-is-not-what-I-hadin- mind problem, but it doesn’t solve all const-related difficulties. For example, suppose that operator[] in TextBlock (and CTextBlock) not only returned a reference to the appropriate character, it also performed bounds checking, logged access information, maybe even did data integrity validation. Putting all this in both the const and the non-const operator[] functions (and not fretting that we now have implicitly inline functions of nontrivial length — see Item 30) yields this kind of monstrosity: - class TextBlock {
- public:
- ...
- const char& operator[](std::size_t position) const
- {
- ...
- ...
- ...
- return text[position];
- }
- char& operator[](std::size_t position)
- {
- ...
- ...
- ...
- return text[position];
- }
- private:
- std::string text;
- };
Ouch! Can you say code duplication, along with its attendant compilation time, maintenance, and code-bloat headaches Sure, it’s possible to move all the code for bounds checking, etc. into a separate member function (private, naturally) that both versions of operator[] call, but you’ve still got the duplicated calls to that function and you’ve still got the duplicated return statement code.
|