const
Objects and const
Member FunctionsLet’s see how the principle of least privilege applies to objects. Some objects need to be modifiable and some do not. You may use const
to specify that an object is not modifiable and that any attempt to modify the object should result in a compilation error. The statement
const Time noon{12, 0, 0};
declares a const
object noon
of class Time
and initializes it to 12 noon. It’s possible to instantiate const
and non-const
objects of the same class.
Attempts to modify a const
object are caught at compile time rather than causing execution-time errors.
Declaring variables and objects const
when appropriate can improve performance— compilers can perform optimizations on constants that cannot be performed on non-const
variables.
C++ disallows member-function calls for const
objects unless the member functions themselves are also declared const
. This is true even for get member functions that do not modify the object. This is also a key reason that we’ve declared as const
all member functions that do not modify the objects on which they’re called.
Defining as const
a member function that calls a non-const
member function of the class on the same object is a compilation error.
Invoking a non-const
member function on a const
object is a compilation error.
An interesting problem arises for constructors and destructors, each of which typically modifies objects. A constructor must be allowed to modify an object so that the object can be initialized. A destructor must be able to perform its termination housekeeping before an object’s memory is reclaimed by the system. Attempting to declare a constructor or destructor const
is a compilation error. The “const
ness” of a const
object is enforced from the time the constructor completes initialization of the object until that object’s destructor is called.
const
and Non-const
Member FunctionsThe program of Fig. 9.17 uses class Time
from Figs. 9.5–9.6, but removes const
from function toStandardString
’s prototype and definition so that we can show a compilation error. We create two Time
objects—non-const
object wakeUp
(line 6) and const
object noon
(line 7). The program attempts to invoke non-const
member functions setHour
(line 11) and toStandardString
(line 15) on the const
object noon
. In each case, the compiler generates an error message. The program also illustrates the three other member-function-call combinations on objects—a non-const
member function on a non-const
object (line 10), a const
member function on a non-const
object (line 12) and a const
member function on a const
object (lines 13–14). The error messages generated for non-const
member functions called on a const
object are shown in the output window.
A constructor must be a non-const
member function, but it can still be used to initialize a const
object (Fig. 9.17, line 7). Recall from Fig. 9.6 that the Time
constructor’s definition calls another non-const
member function—setTime
—to perform the initialization of a Time
object. Invoking a non-const
member function from the constructor call as part of the initialization of a const
object is allowed.
Line 15 in Fig. 9.17 generates a compilation error even though member function toStandardString
of class Time
does not modify the object on which it’s called. The fact that a member function does not modify an object is not sufficient—the function must explicitly be declared const
.