TICS Coding Standard Viewer 
TIOBE Software Quality Framework
Print-friendly version
©TIOBE Software www.tiobe.com
 
C++ Coding Standard
Search

Rule:  INT#024

This rule is Obsolete
Synopsis:A member function that gives non-const access to the representation of an object must not be declared const
Language:C++
Severity Level:2
Category:Class Interface


Description:

A member function that gives non-const access to the representation of an object must not be declared const, since the object has no control over possible modifications through such pointers or references. The solution is to properly overload member functions with respect to constness.

The following piece of code allows a string to be modified by using the indexing operator to access individual characters.

EmcString name = "John Bauer";
name[0]  = 'B';             // OK

The implementation returns a reference to a character that is part of the representation for the string and that can be assigned to. Here, the indexing operator indirectly modifies the object.

The EmcString class has overloaded operator[] with respect to constness to prevent const objects to be indirectly modified this way.

class EmcString
{
   public:
      EmcString(const char* cp);
      size_t length() const;
      // ...
      // Non-const version
      char& operator[](size_t index); 
      // Const version
      char  operator[](size_t index) const;
      // ...
   private:
      size_t lengthM;  // Length of string
      char*  cpM;      // A pointer to the characters
};

The string is represented by two data members cpM, the character array, and lengthM, the length of the string.

The implementation of the indexing operators are straightforward. They just return a reference to the character specified by the index parameter, as long as the index is within bounds.

char& EmcString::operator[](size_t index)
{
   assert(index < lengthM);
   return cpM[index];
}

The compiler would not complain if this indexing operator is declared const, since it is not the pointer cpM that is modified, only what it points at. By doing that, one operator member function would have been enough, which would be a benefit for the person maintaining the class. since the fewer member functions the class has, the easier it is to maintain.

From the user's perspective it would be wrong to const declare the indexing operator returning a reference, since that would open up the possibility that a constant string could change value. Here, the compiler's interpretation of const would not be the same as the programmer's.

const EmcString pioneer = "Roald Amundsen";
// pioneer[0]  = 'M';  Should NOT be legal!!

We want to allow each individual character of a const declared string to be accessed, but not modified. The correct way to do that is to overload the indexing operator with respect to constness. The const member function does not return a reference so the string cannot be modified through assignment to the return value.

const EmcString s = "hello";

size_t length = s.length();

for (size_t j = 0; j < length; j++)
{
   // OK: Read only
   cout << "char " << j << ": " << s[j] << endl;  
}


Literature References:
ISC++ Rule 7.12