Todo objeto no C ++ é mutável se não indicado de outra forma?
Em Python e Javascript, não posso alterar strings, tupla, unicodes. Eu queria saber se existe algo em C ++ que é imutável ou que todo objeto é mutável e eu tenho que usar o const
qualificador de tipo para torná-lo imutável.
Respostas:
A imutabilidade é bem compreendida há algum tempo. Python, Java e C ++ têm diferentes modelos de memória que dificultam as comparações diretas. O autor do artigo que você citou originalmente não parece conhecer C ++.
Como em Python, Java e na maioria das linguagens de múltiplos paradigmas, C e C ++ permitem mutabilidade por padrão. Isto é o que os programadores geralmente querem: se eu tiver uma
String x
variável, desejo poder atribuir um novo valorx = "foo"
.O sistema const em C e C ++ permite uma grande imutabilidade sutil que falta em Python, Java e até Scala. Se uma função C ++ usa a
const std::string&
ou aconst char*
, promete (e o compilador garante, até certo ponto), que essa função não irá (não pode!) Alterar o conteúdo dessa string. Dado um objeto const, só podemos invocar métodos desse objeto que também são marcados como const. Se uma classe C ++ tiver apenas membros públicosconst
, o objeto será efetivamente imutável.No entanto, isso às vezes é confuso, pois os objetos C e C ++ são locais de memória e variáveis são nomes para locais de memória. Por outro lado, variáveis em Python e Java são nomes para ponteiros para objetos. Em uma linguagem com semântica de referência,
x = y
significa "faça x apontar para o mesmo objeto que y". Como estamos apenas copiando ponteiros, isso é possível com objetos imutáveis. Em uma linguagem com semântica de valores como C ++, significa "atualizar o conteúdo dex
com o conteúdo dey
". Portanto, se a redistribuição de uma variável for desejada em C ou C ++, a variável pode não ter um tipo const. Para fazer isso com objetos imutáveis, teríamos que usar um ponteiro explicitamente.O fato de Java e Python usarem objetos de sequência imutáveis é uma decisão de design fundamental, mas não está diretamente conectada aos benefícios da imutabilidade em um ambiente de multithreading. Uma razão é que literais de string no código-fonte podem ser agrupados, o que reduz o número de objetos. Isso também é possível em C / C ++. Em C ++, o literal
"foo"
tem tipoconst char[4]
(o quarto caractere é o final'\0'
). Outro motivo é que as entradas em conjuntos e chaves em dictos / mapas não devem ser alteradas. Como as seqüências de caracteres são usadas amplamente como chaves de ditado (a maioria dos objetos Python é um ditado), a imutabilidade remove uma fonte comum de erros. Em Java, outro motivo para sequências imutáveis é o modelo de segurança Java. Todos esses motivos não têm nenhuma relação com o multithreading.Se o Java fosse construído com imutabilidade em mente, a linguagem teria uma aparência muito diferente. Embora seja intimamente inspirado pelo C ++, os designers tentaram criar uma linguagem muito mais simples, livrar-se do const é um desses passos. A coisa Java equivalente a uma referência const C ++ é um adaptador ou decorador que implementa qualquer método de mutação como
throws new NotImplementedException()
e encaminha chamadas de método não mutante para a coleção real. O fato de a coleção java.util interagir com todos implica em mutabilidade é um sinal claro de que eles não se esforçaram por um idioma de imutabilidade em primeiro lugar.A solução que o Java apresentou para solucionar problemas de concorrência não era imutabilidade, mas um bloqueio generalizado. Cada objeto contém um mutex que pode ser usado para
synchronized
blocos ou métodos inteiros. Como se vê, isso não é bom para o desempenho, não se adapta muito bem e é propenso a erros - você ainda precisa lidar com um estado global mutável.fonte
mut
palavra - chave e onde a mutabilidade desnecessária é sinalizada pelo compilador) tendem a apoiar minha hipótese: no Rust, você tem muito maislet
ligações do que as que possuilet mut
.for x in 1..10
não é usadolet mut
para definir a variável do loop, mas obviamente requer alguma mutabilidade (apenas no nível do loop, não dentro do corpo do loop).const T o = [&]{T o; o.init(...); return o;}();
... sim, para APIs que não foram projetadas com imutabilidade em mente.Quase. A própria linguagem trata tudo como mutável, a menos que você use
const
, mas ainda é possível criar objetos imutáveis sem dizer ao compilador que são imutáveis, simplesmente não fornecendo uma maneira de mutá-los.Por exemplo, pegue esta classe:
Instâncias de
MyClass
são imutáveis, porque não há como modificá-las - mas em nenhum lugar do código se afirma que elas são imutáveis. (É da mesma maneira que instâncias daString
classe Java são imutáveis)fonte
delete
operador de atribuição de cópia aqui também garante que não seja possível atribuir a partir de uma referência de valor através da operação de atribuição de movimento?value
const e a declarargetValue()
uma função const.Não, há uma exceção: Lambdas e por extensão os objetos que capturam são imutáveis por padrão:
Então, em vez de adicionar
const
para torná-lo imutável, você adicionamutable
para torná-lo nãoconst
.fonte