En C++ existen varios modificadores de tipos de variables. El más conocido es const. Aquí queremos hablar de un modificador que de alguna forma es el contrario de const: El modificador mutable.

El modificador mutable quiere decir: Este miembro sigue siendo variable aunque la instancia de su clase sea declarada const. Fuera de una clase, mutable no tiene sentido.

La pregunta es: ¿por qué alguien quiere tener un miembro de clase variable cuando ha declarado el objeto const? Vemos un ejemplo clásico de la programación multi-hilo.

class Lista
{
public:
    // Una función que modifica la instancia
    void añadeElemento(const int nuevo_valor)
    {
        while (mutex)
        {
            // Bloquea el objeto para acceso exclusivo
            mutex = true;
            // Modifica el objeto
            una_lista.push_back(nuevo_valor);  
            // Libera el objeto
            mutex = false;
        }
    }
    
    // Una función que lee la instancia
    std::list<int> devuelveLista() const
    {
        std::list<int> copia;
        while (mutex)
        {
            // Bloquea el objeto para acceso exclusivo
            mutex = true;  
            // Crea una copia temporal
            copia = una_lista;
            // Libera el objeto
            mutex = false;
        }
        // Con la copia el hilo puede leer cuanto quiera
        return copia;  
    }
    
private:
    std::list<int> una_lista;
    mutable bool mutex;
};

La clase Lista contiene un objeto complejo una_lista y un mutex. En un entorno multi-hilo, todos los hilos podrían querer acceder a la lista potencialmente al mismo tiempo. No hay problema mientras todas los hilos quieren leer, pero esto se cambia si uno quiere escribir. Añadir un nuevo elemento requiere cambiar varias variables dentro de la lista. Con un poco de mala suerte (no mucha), un hilo intenta leer de la lista cuando el cambio todavía no está completo y obtiene así datos corruptos. Por esta razón, se bloquea la lista con un mutex. (Una tipo de mutex no muy sofisticado, pero para nuestro ejemplo nos sirve.) Mientras un hilo tiene el mutex (asignando true, los otros se deben esperar en el bucle while.

Si un hilo quiere leer la lista con la función devuelveLista, entonces, conceptualmente, lo puede hacer sobre un objeto constante. Leer no modifica el contenido del objeto y, en consequencia, la función devuelveLista está declarada const. No obstante, el miemro mutex también sería constante en este caso. Y ahora, ¿cómo se puede bloquear la lista contra el acceso de escritura en una función const?

La solución es declarar el mutex mutable. Así el mutex sigue siendo variable mientras el resto de la clase es constante.

Es obvio que sobrescribir el carácter constante de un objeto con mutable invita a crear un mal diseño. Por eso úsalo con consideración. Un miembro mutable suele contener meta-información como un guardian de acceso (como un mutex), o un contador que cuenta cuántas veces se ha leído un dato. Los datos mismos nunca tienen razón de ser mutable.

Lectura adicional