[ fromfile: constmembers.xml id: constmembers ]
When a class member function ClassX::f()
is invoked through an object objx
objx.f();
we refer to objx
as the host object.
The const
keyword has a special meaning when it is applied to a (non-static
) class member function.
Placed after the parameter list, const
becomes part of the function signature and guarantees that the function will not change the state of the host object.
A good way to look at the way const
modifies member functions is to realize that each non-static
member function has an implicit parameter, named this
, which is a pointer to the host object.
When you declare a member function to be const
, you are telling the compiler that, as far as the function is concerned, this
is a pointer to const.
To explain how const
changes the way a function is invoked, we look at how the original C++ to C preprocessor dealt with member functions.
Because C did not support overloaded functions or member functions, the preprocessor translated the function into a C function with a "mangled" name that distinguished itself from other functions by encoding the full signature in the name.
The mangling process also added an extra implicit parameter to the parameter list: this
, a pointer to the host object.
Example 2.21 shows how member functions might be seen by a linker after a translation into C.
Example 2.21. src/const/constmembers/constmembers.cpp
#include <QTextStream> #include <QString> class Point { public: Point(int px, int py) : m_X(px), m_Y(py) {} void set(int nx, int ny) { m_X = nx; m_Y = ny; } QString toString() const { // m_X = 5; m_Count++; return QString("[%1,%2]").arg(m_X).arg(m_Y); } private: int m_X, m_Y; mutable int m_Count; }; int main() { QTextStream cout(stdout); Point p(1,1); const Point q(2,2); p.set(4,4); cout << p.toString() << endl; //q.set(4,4); return 0; }
<include src="src/const/constmembers/constmembers.cpp" href="src/const/constmembers/constmembers.cpp" id="constmemberscpp" mode="cpp"/>
In a real compiler, the mangled names for set
and print
would be compressed significantly, to save space and hence be less understandable to a human reader.
Notice that mutable members can be modified inside const
member functions, but regular data members cannot.
You can think of the const
in the signature of print()
as a modifier of the invisible this
parameter that points to the host object.
This means that the memory pointed to by this
cannot be changed by the action of the print()
function.
The reason that the assignment x = 5;
produces an error is that it is equivalent to this->x = 5;
.
The assignment violates the rules of const
.
Suppose that you need to work with a project that contains classes that do not use const
correctly. When you start to add const
to member functions, parameters, and pointers that need it, you may find that those changes generare a cascade of compiler errors that prevent you from building the project until const
has been correctly added throughout the project. When const has finally been added to all the correct places, you can say that your classes are const correct.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |