C++

Const Correctness

12 question(s)

What does const mean in C++?

Beginner
const declares that something won't be modified after initialization. Applied to a variable, it makes it read-only; to a function parameter, it promises not to change the argument; to a member function, it promises not to modify the object. const enables compiler enforcement of immutability, safer interfaces, and certain optimizations.
const int max = 100;   // cannot be reassigned
void print(const std::string& s); // won't modify s
Real-world example Passing a large object by const reference documents and enforces that the function won't change it.

Common follow-ups: What can const be applied to? | How does it help callers?

References & Pointers Const Correctness Const Correctness

What is a const member function?

Beginner
A const member function (declared with const after the parameter list) promises not to modify the object's observable state and can be called on const objects. Inside it, member variables are treated as const (unless marked mutable). Marking read-only methods const is core to const-correctness and lets them be used on const instances.
struct Box {
    int size() const { return n; } // doesn't modify *this
    int n = 0;
};
Real-world example A getter is marked const so it can be called on a const Box passed to a function.

Common follow-ups: Can a const method modify members? | Why can const objects only call const methods?

OOP & Classes Const Correctness Const Correctness

What is the difference between const pointer and pointer to const?

Intermediate
'Pointer to const' (const int* p) means the pointed-to value can't be changed through p, but p can point elsewhere. 'Const pointer' (int* const p) means p can't be repointed, but the value can change. 'Const pointer to const' (const int* const p) fixes both. Reading right-to-left clarifies which part is const.
const int* a;      // value const, pointer mutable
int* const b = &x; // pointer const, value mutable
const int* const c = &x; // both const
Real-world example An API returns a const int* so callers can read but not modify the internal buffer, while reusing the pointer.

Common follow-ups: How do you read the declarations? | Which part does each const fix?

References & Pointers Const Correctness Const Correctness

What is the mutable keyword?

Intermediate
mutable allows a member variable to be modified even inside a const member function (or of a const object). It's used for members that don't affect the object's logical/observable state—caches, memoized values, mutexes, or usage counters—so a logically-const method can still update them.
struct Cache {
    int get() const { hits++; return value; } // hits is mutable
    mutable int hits = 0;
    int value = 0;
};
Real-world example A cache's hit counter is mutable so read-only accessors can still increment it.

Common follow-ups: When is mutable appropriate? | What is 'logical constness'?

OOP & Classes Const Correctness Const Correctness

What is the difference between physical and logical constness?

Advanced
Physical (bitwise) constness means no bits of the object change. Logical constness means the object's observable/meaningful state doesn't change, even if some internal bits (like a cache or mutex) do. const member functions guarantee logical constness; mutable members let internal, non-observable state change while preserving logical constness.
// A const method that lazily caches a result maintains
// logical constness while mutating a mutable cache member.
Real-world example A lazily-computed, cached hash preserves logical constness though the cache member physically changes.

Common follow-ups: Which does const guarantee? | How does mutable relate to this?

Const Correctness OOP & Classes Const Correctness

Why should you pass objects by const reference?

Beginner
Passing large objects by const reference (const T&) avoids copying (better performance) while promising not to modify the argument (safer, clearer interface, and callable with temporaries and const objects). It's the standard way to pass read-only parameters that are expensive to copy, like strings and containers.
void process(const std::vector<int>& data); // no copy, read-only
Real-world example Changing a parameter from by-value to const reference removes a costly copy of a large vector on every call.

Common follow-ups: What does it avoid? | Can it accept temporaries?

References & Pointers Move Semantics Const Correctness

How do you overload a member function on const?

Advanced
You can provide both const and non-const overloads of a member function; the compiler picks the const version for const objects and the non-const version for non-const objects. This is common for accessors that return a const reference for const objects and a mutable reference otherwise, avoiding code duplication (or using a const_cast helper).
struct V {
    int& at(int i)             { return d[i]; }
    const int& at(int i) const { return d[i]; }
    int d[10];
};
Real-world example A container's operator[] has const and non-const overloads so const containers return read-only references.

Common follow-ups: Which overload does a const object call? | How can you avoid duplicating the body?

Operator Overloading OOP & Classes Const Correctness

What is const_cast and when is it (rarely) appropriate?

Intermediate
const_cast adds or removes const/volatile qualifiers from a pointer or reference. Removing const to modify an object that is genuinely const is undefined behavior; const_cast is only safe to remove const you know was added artificially (e.g., interfacing with a legacy non-const API on an object that is actually mutable). It's a code smell to be used sparingly.
void legacy(char* s);
void wrap(const char* s) { legacy(const_cast<char*>(s)); } // only if legacy won't modify
Real-world example const_cast bridges to a legacy C API that lacks const, on data known to be mutable.

Common follow-ups: When is removing const undefined behavior? | Why is const_cast a code smell?

Casting & Conversions Const Correctness Const Correctness

What is a constant reference and why is it useful?

Beginner
A const reference (const T&) is a reference through which the referent can't be modified. It's useful for read-only aliasing without copying, for function parameters, and because a const reference can bind to a temporary (extending its lifetime to the reference's scope), which a non-const lvalue reference cannot.
const std::string& r = std::string("temp"); // binds temporary
Real-world example A function takes const std::string& so it can be called with both variables and string literals without copying.

Common follow-ups: Can a const reference bind to a temporary? | Why can't a non-const lvalue reference?

References & Pointers Const Correctness Const Correctness

How does const propagate with member objects and pointers (const propagation)?

Advanced
When an object is const, its non-mutable members are treated as const, so member functions called on them must be const. However, if a member is a raw pointer, const only applies to the pointer itself, not the pointee—so a const method can still modify what a member pointer points to. std::experimental::propagate_const (or a wrapper) can extend constness to the pointee.
struct S {
    int* p;
    void f() const { *p = 5; } // allowed: pointee not const
};
Real-world example A const method unexpectedly mutates data via a member raw pointer because const doesn't propagate to the pointee.

Common follow-ups: Does const propagate through a member pointer? | What is propagate_const?

References & Pointers Const Correctness Const Correctness