The const Keyword
Extreme Encapsulation
Humble Beginnings• There are often cases in coding
where it is helpful to use a const variable in a method or program.– Even when working with fixed values, it
is best to abstract them with variable names.• It’s more helpful (debugging-wise) to see
“array_length” than tons of copies of the same number everywhere.
Humble Beginnings• With object-orientation, many classes
may take permanent values which are unique to each instance of the class, specified during initialization.– As these should not change at any point
in the object’s lifetime, const makes sense.
Humble Beginnings• The use of const is fairly
straightforward for the primitive data types – the basic building blocks of the language.
• Things get more complicated when we use const with pointers and with objects.
const and Objects• What would it mean for an object to
be const?
const and Objects• What would it mean for an object to
be const?– If declared const, an object should not
be modifiable.– Problem: how can we use its methods
while being sure not to modify it?
const and Objects• In C++, whenever a variable is
declared const, no modifications are allowed to it, in a by-value manner.– As the compiler is not powerful enough
to ensure that its methods do not modify it, by default C++ blocks all use of any class methods.• This would be a huge problem for
encapsulation.
const and Objects• The C++ solution to the problem this
poses: functions can be declared const.– Appending the const keyword to a
function signifies that the method is not allowed to alter the class in any manner.
– Inside that method, all fields of the class will be treated as if they were declared const.
const and Objects• Let us now examine how this would
look in code, through our frequent Person class example.
A First Objectpublic class Person{
private:const string name;int age;
public:Person(string name, int age)string getName() const;int getAge() const;void haveABirthday();
}
A First Objectstring Person::getName() const{
return this->name;}
int Person::getAge() const{
return this->age;}
A First Objectpublic void haveABirthday(){
this->age++;}
• Note: declaring this method as const would result in a compile-time error, as age would be treated as const within the method.
const and Objects• Which of the following code lines is
invalid?
const Person p(“Joshua”, 28);
string name = p.getName();int age = p.getAge();p.haveABirthday();
const and Objects• Which of the following code lines is
invalid?
p.haveABirthday();
• As this method is not declared const, a compile-time error would result from this method being called upon const p.
Exercise 1• Bust out your Person code and
modify it to make const methods• Modify your main() to declare a const
person object• Try to access the object with all
methods• Compile & run• Fix
const and Pointers• When we add pointers into the mix,
things get even more interesting.–What might we wish to be constant?• The stored address / pointer• The referenced value
const and Pointers• In order to have a const pointer to a
changeable value, use the following syntax:– int* const myVariable;
• To allow the stored address to be replaced, but have the referenced value be otherwise unchangeable:– const int* myVariable;
const and Pointers• Using the syntax below, while obj is
declared by-reference, the compiler will block any attempts to modify its contents:– const Object* obj;– The referenced object obj is considered
constant.
const and Pointers• The simplest way to think of it – read const definitions from right to left.– int* const myVariable;– const int* myVariable;• When const is fully on the left, it modifies
the direct right instead.• int const* myVariable;
– Is the same definition, with different ordering.
const and Pointers• While very powerful, const syntax
can get rather crazy:– const Object* const obj;– Translation:• const Object* const obj;• A const reference…• const Object* const obj;• to a const Object.
const and Pointers• Similar rules apply to arrays.– The following may store a constant
reference to an array with changeable values:• int* const myVariable;
– The following may store a replaceable reference to arrays whose values are treated as const:• const int* myVariable;
const and Pointers• Example:int* initArray = new int[6];int* const myVariable = initArray;myVariable = new int[3];
//Above: Not legalmyVariable[2] = 3; // Legal!
…
const and Pointers• Example:int* initArray = new int[6];const int* myVariable = initArray;myVariable = new int[3];
//Above: Legal, not initializedmyVariable[2] = 3; //Illegal!
…
Exercise 2• Code up the previous examples with
four int arrays– Non-const– Const int*– Int* const– Const int* const
• Code main() to access each of the array types in each way
• Compile, observe, comment out code that compiler doesn’t like
const and Parameters• Suppose a method is defined as
follows:
void someMethod(const Object* obj)
• What implications would this have?
const and Parametersvoid someMethod(const Object* obj)
• What implications would this have?– As obj is defined const Object*, we
would get a pointer to an unmodifiable instance of Object.
–What are we able to pass in as an argument to obj?
const and Parametersvoid someMethod(const Object* obj)
• Which of these would be proper calls?– const Object obj();someMethod(&obj);
– Object* obj = new Object();someMethod(obj);
const and Parametersvoid someMethod(const Object* obj)
• Which of these would be proper calls?– const Object obj();someMethod(&obj);
– Object* obj = new Object();someMethod(obj);
Trick Question! Both!
const and Parametersvoid someMethod(const Object* obj)
• While the original argument to methods of this form do not have to be const, they become const within the method.
const and Parametersvoid someMethod(Object* obj)
• Which of these would be proper calls?– const Object obj();someMethod(&obj);
– Object* obj = new Object();someMethod(obj);
const and Parametersvoid someMethod(Object* obj)
• Which of these would be proper calls?– const Object obj();someMethod(&obj);
– Object* obj = new Object();someMethod(obj);
const and Parameters• const objects cannot be passed by-
reference to non-const function parameters.– As there is no guarantee that the
referenced object will not be modified when passed to a non-const parameter, the compiler blocks this.
– For value types, since a separate value is created, that separate copy is safe for the called function to edit.
const and Parameters• const objects cannot be passed by-
reference to non-const function parameters.– An interesting consequence of this:
void someMethod(string &str);
someMethod(string(“Hello World”));// Will be a compile-time error// due to the compile-time constant.
const and Parameters• const objects cannot be passed by-
reference to non-const function parameters.– An interesting consequence of this:
void someMethod(const string &str);
someMethod(string(“Hello World”));// Will work without issue!
const and Parameters• A signature of the latter type –void someMethod(const string &str)
has one additional benefit.– Since str is passed by reference here,
the system doesn’t have to copy its value…
– And since str is declared const, its value cannot be changed.
const and Parameters• A signature of the latter type –void someMethod(const string &str)
has one additional benefit.– Consider if this were a very large string.• Or, just some very large object.
– This makes the program more efficient in terms of run-time and in terms of memory use.
const and Return Values• const may also be applied to return
values!– Consider if we were to return a
reference to an object’s internal field.– Rather than copy the internal object, we
may wish to return it while blocking write access within the object.
Example: const Object* gimmeObject();
const and Return Values• While not mentioned thus far in
class, this also affects the other return-by-reference type…
const Object& gimmeObject();
• This form, if not const, allows code to both modify that object and assign directly to its original variable!
Exercise 3• Code const and non-const parameter
methods for some object• Try passing const and non-const
instances into the methods• Compile and observe
const Design• const allows the programmer to
share values freely with other parts of the program while making them write-only.– This can be very useful for
encapsulation!• Return an array/internal reference “const
type*” – the same array is used, but edits are prohibited!
Top Related