C++ PROGRAMMING ยท 14 MIN STUDY

Const correctness and member functions

Use const to express which values and objects a function promises not to modify, making interfaces safer and easier to understand.

Learning objectives

  • Explain what const protects.
  • Distinguish a pointer to const data from a const pointer.
  • Declare member functions that do not modify observable object state.
  • Use const references for read-only parameters.

Prerequisites: variables, functions, pointers, and references. Review Variables, Functions, Pointers, and References first.

Const objects and variables

A const object cannot be modified through that name after initialization. It must be initialized when created.

const int maximum{100};
// maximum = 120; // ERROR: cannot modify a const object

Const communicates a constraint to the compiler and to readers. It is not merely a comment.

Const references for input

When a function needs to inspect a potentially large object without copying or modifying it, a const reference is often a good parameter type.

#include <string>

bool is_empty(const std::string& text) {
    return text.empty();
}

The function can call const operations on text, but cannot modify it through this reference.

Const and pointers

DeclarationMeaning
const int* pPointer to const int: cannot modify the int through p; p may point elsewhere.
int* const pConst pointer to int: p cannot point elsewhere; the int may be modified through p.
const int* const pConst pointer to const int: neither reassignment of p nor modification through p is allowed.
int first{1};
int second{2};

const int* view = &first;
view = &second; // OK: pointer can be reseated
// *view = 3;   // ERROR: cannot modify through pointer

int* const fixed = &first;
// fixed = &second; // ERROR: pointer itself is const
*fixed = 3;          // OK: modifies first

Const member functions

A const member function promises not to modify the object's observable non-mutable state through the implicit object parameter. Put const after the parameter list.

class Rectangle {
    double width;
    double height;

public:
    Rectangle(double w, double h) : width{w}, height{h} {}

    double area() const {
        return width * height;
    }

    void scale(double factor) {
        width *= factor;
        height *= factor;
    }
};

Calling area() is allowed on a const Rectangle; calling scale() is not. This lets the class expose read-only operations clearly.

Logical constness and mutable

Sometimes an implementation updates internal bookkeeping without changing the value users observe, such as a cached calculation. C++ provides mutable for carefully chosen data members. Use it sparingly: const should remain a meaningful promise to callers.

Common mistakes

  • Putting const in the wrong place in a pointer declaration.
  • Forgetting the trailing const on a read-only member function.
  • Passing large read-only objects by value when a const reference is more appropriate.
  • Using const_cast to force modification; modifying an object that was originally defined const is undefined behavior.

Practice exercises

  1. Write a function parameter that accepts a read-only std::vector<int> without copying it.
  2. What does int* const p mean?
  3. Can a const object call a non-const member function?
  4. Why should a getter such as area() normally be const?

Solutions

Show exercise solutions
  1. void inspect(const std::vector<int>& values).
  2. It is a const pointer to a modifiable int: the pointer cannot be reseated, but the pointed-to int can be modified through it.
  3. No. A const object can call only member functions that are const-qualified (and certain other permitted functions).
  4. It does not change the object's observable state, so marking it const allows use through const objects and documents the contract.

Summary

Use const to express read-only intent. A const reference avoids copying while preventing modification through that reference. Pointer const placement matters. Const member functions make class interfaces safer and more flexible.

References