Table of Contents

C++ Logical constness

Logical constness is the principle that a const member function doesn't change the object's observable state, even if it modifies internal state (like a cache). The mutable keyword marks members that can be modified by const functions, indicating they don't affect observable behavior.

Use mutable carefully for caches and lazy-initialized state; document why members are mutable so readers understand the invariant.

Example

This example shows logical constness with mutable caching.

// compile: g++ -o logical logical.cpp
// run: ./logical
// description: logical constness: mutable for internal caches
 
#include <iostream>
#include <string>
 
class User {
private:
    std::string first_name;
    std::string last_name;
    mutable std::string cached_full_name;
    mutable bool cache_valid = false;
public:
    User(const std::string& f, const std::string& l)
        : first_name(f), last_name(l) {}
 
    const std::string& fullName() const {
        if (!cache_valid) {
            cached_full_name = first_name + " " + last_name;
            cache_valid = true;
        }
        return cached_full_name;
    }
};
 
int main() {
    const User u("John", "Doe");
    std::cout << u.fullName() << "\n";  // const function, but modifies mutable cache
 
    return 0;
}