A mutable
palavra-chave é uma maneira de perfurar o const
véu que você coloca sobre seus objetos. Se você tiver uma referência const ou ponteiro para um objeto, não poderá modificar esse objeto de nenhuma maneira, exceto quando e como está marcadomutable
.
Com sua const
referência ou ponteiro, você está limitado a:
- acesso de leitura apenas para quaisquer membros de dados visíveis
- permissão para chamar apenas métodos marcados como
const
.
A mutable
exceção permite que você agora possa gravar ou definir membros de dados marcados mutable
. Essa é a única diferença visível externamente.
Internamente, os const
métodos visíveis para você também podem gravar nos membros de dados marcados mutable
. Essencialmente, o véu const é perfurado de forma abrangente. Cabe ao projetista da API garantir que mutable
isso não destrua o const
conceito e seja usado apenas em casos especiais úteis. A mutable
palavra-chave ajuda porque marca claramente os membros de dados que estão sujeitos a esses casos especiais.
Na prática, você pode usar const
obsessivamente em toda a sua base de código (você deseja essencialmente "infectar" sua base de código com a const
"doença"). Neste mundo, ponteiros e referências sãoconst
muito poucas exceções, produzindo código mais fácil de raciocinar e entender. Para uma digressão interessante, procure "transparência referencial".
Sem a mutable
palavra-chave, você será forçado a usar const_cast
para lidar com os vários casos especiais úteis que ela permite (armazenamento em cache, contagem de referências, dados de depuração etc.). Infelizmente, const_cast
é significativamente mais destrutivo do que mutable
porque força o cliente da API a destruir a const
proteção dos objetos que ele está usando. Além disso, causa const
destruição generalizada : o uso de const_cast
um ponteiro ou referência constante permite acesso irrestrito à gravação e à chamada de método a membros visíveis. Por outro lado, mutable
exige que o designer da API exerça controle refinado sobre as const
exceções e, geralmente, essas exceções estão ocultas nos const
métodos que operam com dados particulares.
(NB refiro-me à visibilidade de dados e métodos algumas vezes. Estou falando de membros marcados como públicos versus privados ou protegidos, que é um tipo totalmente diferente de proteção a objetos discutido aqui .)