Mutable es un modificador de tipo para los atributos de las clases, vamos a ver como funciona y hacer un ejemplo práctico de uso, para ver la importancia que tienen.

Consideraciones previas

En C++ sabemos que si tenemos una clase, independientemente del acceso que tengan sus atributos, si marcamos una función como constante, no podemos modificar o mutar los atributos de esa clase.

Os mostramos un ejemplo:

class Hey
{
public:
    mutable unsigned int counter                = 0;
    unsigned int                 another counter = 0;

    Hey(){};

    void inc()const
    {
            counter += 1;
    }

    void inc2()
    {
            other_counter += 1;
    }
};
    
int main() {
    Hey hey;
    return 0;
}

En esta clase de ejemplo tenemos dos atributos counter y another_counter.

El segundo es un atributo normal, ya que es un entero sin signo, con lo cual, si tenemos una función cualquiera dentro de la clase y la intentamos modificar, no hay problema.

Vamos a ver otro ejemplo:


class Hey
{
public:
    mutable unsigned int counter                = 0;
    unsigned int                 another counter = 0;

    Hey(){};

    void inc()const
    {
            other_counter += 1;
    }

    void inc2()
    {
            other_counter += 1;
    }
};
    
int main() {
    Hey hey;
    return 0;
}

Si intentamos modificar ese atributo dentro de una función que está marcada como constante, el compilador nos muestra un error indicando que el objeto other_counter es solo de lectura, porque le estamos diciendo que todo lo que haya dentro de esa función sólo se puede leer y no se puede modificar.

Usos de mutable en C++

En algunos casos nos interesa que el compilador nos avise si estamos intentando modificar algún atributo que no queremos, pero cuando intentamos mezclar estas dos estas dos opciones, que se puedan mutar y algunos que no se puedan mutar, es más complicado.

Para estos casos existe mutable, que es un modificador que le indica el compilador que aunque un elemento está en una función constante, que está definida para que no se puedan modificar los elementos de la clase, aun así podamos modificarlo.

Os lo mostramos:

class Hey

{ public: mutable unsigned int counter = 0; unsigned int another counter = 0; Hey(){}; void inc()const { counter += 1; } void inc2() { other_counter += 1; } }; int main() { Hey hey; return 0; }

En este caso podemos comprobar como el código compila sin errores.