Como você se tornou um convertido de correção const? [fechadas]

25

Após 15 anos de C ++, ainda não aprendi a amar o uso de const. Eu entendo o seu uso, mas nunca estive realmente em uma situação em que estar constantemente correto evitasse o problema que estava enfrentando.

Então, como você adorou os benefícios dos consts?

grunhir
fonte
3
Penso que a correção constante é mais correta do que uma ferramenta para resolver um problema como um operador if constrcut ou sizeof.
Legenda2k
9
"O motivo pelo qual const funciona em C ++ é porque você pode descartá-lo. Se você não pudesse descartá-lo, seu mundo seria péssimo." - Anders Hejlsberg
Mason Wheeler
1
const também é um modificador do tipo C e existe desde o primeiro padrão ANSI C.
Huperniketes
Sendo mimado por Java / C #, sou do tipo paranóico que adora deixar afirma qualquer chance que eu tiver. O que pode dar errado vai dar errado. Se houver uma assistência em tempo de compilação ou em tempo de execução, conte comigo! Tornei-me um convertido assim que ouvi sobre isso 3-4 vezes e segui uma parte deste link (o suficiente para ver a sintaxe, não precisava ler sobre o porquê): ability.com/Cpp/const.html Só porque algo ainda não apareceu na minha cara ... é preciso pouco esforço para ser constante, e não dói. Confira os pensamentos de Joel: joelonsoftware.com/articles/Wrong.html
Job

Respostas:

28

Bem, eu não estava convencido até tentar abraçar a filosofia.

Comecei por colocar constmembros realmente somente leitura dos meus argumentos mais básicos de membros de classe e funções de membro.

A partir daí, não consegui mais compilar. Então eu perseverei em entrar no código usando essas classes básicas, ver se as constadições anteriores eram realmente legítimas em comparação com o uso que eu fiz delas. Isso me ajudou a corrigir alguns erros no caminho, à medida que adicionava constance a outras partes do código.

É contagioso. A maior parte do código ficou ainda mais constante e achei mais fácil depurá-lo, porque você fica confiante de que o compilador o interromperá se você começar a modificar algo que não deveria.

Depois que o aplicativo foi executado novamente, ficou mais rápido (tive que alterar alguns algoritmos que descobri que não eram adequados para o trabalho), com muito menos erros e mais fácil de entender ao ler o código.

Eu estava convencido.

Agora, acho que é ainda melhor quando você usa muitas asserções, além da constness, porque isso faz você se sentir confiante quando precisa escrever um novo código ou modificar o código atual. Você sabe que o compilador o interromperá, se necessário. Ele permite que você esqueça de verificar tudo o que não deve modificar e, assim, terá mais tempo para pensar em pensamentos específicos de negócios ou arquitetônicos.

Klaim
fonte
8
+1 para contagioso, o que significa essencialmente que você deve se tornar um convert constante ou evitá-lo completamente.
Martin Wickman
Você também não precisa confiar em bibliotecas que não fazem const const. Sua abordagem não funciona quando significa que você não pode chamar nenhuma das funções da GUI porque elas não são constantes - ou você precisa descartá-la em todas as chamadas da GUI.
Martin Beckett #
4
+1 para "achei mais fácil depurar", eu uso constaté mesmo para variáveis ​​locais que sei que não precisarei alterar. Dessa forma, ao ler o código, posso passar rapidamente sobre um ifou um forou mais: minha variável é uma constante, eu sei que não vai mudar! Eu não poderia me importar menos com otimizações, mas tenho um cérebro limitado e poucos níveis de indentações + correção de const ajudam muito!
Matthieu M.
@MatthieuM .: Você já pensou em mudar para Haskell? ;-)
Giorgio
@Giorgio: Eu explorei isso, até cheguei a comprar "Real World Haskell". Para ser sincero, não estou empolgado com a preguiça por padrão e com os muitos operadores enigmáticos que surgiram.
Matthieu M. 29/01
15

Eu nunca fui um defensor da programação orientada a objetos e, se alguma coisa eu cresci menos, mais aprendi sobre programação em geral. Como eu estudei diferentes paradigmas de programação, eu percebi que a imutabilidade é um dos os conceitos centrais da concepção do programa, afetando software escrito de acordo com qualquer filosofia. É extremamente importante na programação funcional, com implicações na otimização e simultaneidade, além das simples garantias de segurança.

Basicamente, tudo o que pode ser imutável provavelmente deveria ser, a menos que você tenha um bom motivo para um estado mutável. Na minha experiência, escrever programas em qualquer idioma em busca desse objetivo leva a um código melhor e mais seguro . Você não tem nada a perder usando constonde aplicável - a imutabilidade é grátis!

(Aliás, eu brinquei com a idéia de criar uma bifurcação do GCC para um dialeto de C ++ no qual todos os tipos são, a constmenos que explicitamente qualificados como mutable. Se houver suporte para tal coisa, eu me comprometerei totalmente em mantê-la e usá-la.)


Do ponto de vista do OO, a imutabilidade reforça o encapsulamento, impedindo o acesso irrestrito à gravação. Reduz o acoplamento entre classes porque objetos imutáveis ​​devem gerenciar completamente seu próprio estado e, assim, se comportar como valores comuns. A correção constante facilita significativamente o processo de comprovação da correção do programa, especialmente no contexto da programação simultânea. Com a semântica de referência C ++ e a referência C ++ 0x rvalue, você pode usar objetos imutáveis ​​sem se preocupar com a sobrecarga de copiá-los por todo o lugar. Além disso, o compilador pode funcionar com uma mágica incrível de otimização, se você estiver trabalhando com objetos imutáveis.

Sei que é péssimo digitar em constqualquer lugar, mas você se acostuma rapidamente e os benefícios se tornam aparentes ao longo do tempo em termos de confiabilidade e manutenção. Não sou um escritor brilhante, e parece ser uma tarefa difícil comprovada, mas sei que a correção constante tem sido imensamente útil para mim como desenvolvedor ao projetar e implementar programas, e acho que a experiência é o melhor professor a esse respeito.

Jon Purdy
fonte
2
Você basicamente disse que a correção constante é uma coisa boa. Você disse que "leva a um código melhor e mais seguro". Você pode dizer o porquê?
David Reis
Estou totalmente no campo da imutabilidade, meu idioma favorito é o Erlang. Mas eu argumentaria que a imutabilidade via const em C ++ não é realmente gratuita. Existem desvantagens, como código menos legível, versões const e não const do mesmo método, ou lançar a constante porque "não havia outra opção".
grok
1
Eu recomendaria não apenas usar mutable, uma vez que tem um significado claro em termos de correção de const. Isso significa que esse objeto de dados pode mudar de maneiras que não afetam o comportamento do objeto e permite coisas como armazenar respostas em cache. Crie outra palavra-chave.
David Thornley
2
@ David Thornley: Por uma questão de consistência, mutableé a escolha lógica. void alter(mutable Point&)faz sentido, assim como mutable int foopara uma variável local, e nenhum desses conflitos com o idioma existente ou o uso existente de mutable. Além disso, Object mutable* mutableparece assustador o suficiente para ser um aviso sobre se é necessário ou correto.
Jon Purdy
Se você fizer o garfo, considere ir com o CLang - deve ser menos doloroso.
gf
6

A vantagem da correção constante é que ela impõe uma disciplina ao programa e facilita o raciocínio sobre partes do programa.

A disciplina é que você precisa saber onde algo pode mudar. A vantagem correspondente é que é mais fácil ver o que um pedaço de código faz quando você pode dizer o que pode estar mudando o estado.

David Thornley
fonte
1
"Os programas devem ser escritos para as pessoas lerem, e apenas para as máquinas executarem". - Abelson & Sussman, SICP
Brandon DuRette
4

Estar constante corrige a correção do design que trato perto de um problema semelhante que não está usando operadores de elenco; portanto, não usando cast e sendo constante, o uso mínimo de mutável - todos esses são indicadores para medir o quão bom é o design, mas não as ferramentas reais para resolver o problema geral em questão.

PS: Fiquei totalmente convencido de constquando compreendi a correção em usá-lo;)

legends2k
fonte
2

Eu vejo duas razões principais para escrever código const-correto. Uma é que o compilador é seu amigo e, usando const, você avisa sobre possíveis erros. A segunda razão é que a correção constante torna o código mais legível. Por exemplo, você sempre sabe quais argumentos da função são entradas e quais são saídas. Você também sabe quais funções de membro modificam o objeto e quais não. Você sabe essas coisas instantaneamente sem precisar ler o código. Isso, é claro, pressupõe um uso muito criterioso de const_cast.

Dima
fonte
2

Eu fui convertido assim que soube que era possível. Fazia sentido para mim do ponto de vista do 'bom estilo de programação'. Existem várias razões pelas quais é uma boa prática estar constante:

  • Legibilidade e compreensão. Se estou lendo o código de outra pessoa e uma função usa uma referência const como parâmetro, sei que o parâmetro deve ser usado apenas como uma variável somente leitura. Esta é uma vitória massiva, especialmente se o código for um ambiente multiencadeado.
  • O compilador pode fazer uso do qualificador const para ajudar na otimização.
  • Digamos que eu tenha um objeto da classe A em uma situação em que não queira que ele mude. Em seguida, as únicas funções-membro que podem ser chamadas para esse objeto são aquelas que são const.
sashang
fonte
2

Para resumir dois pontos que foram abordados em outras respostas e adicione um novo:

  • constdocumenta o código para os usuários da sua API. Ele forma um contrato entre uma função e seu chamador, de que a função não modificará seus parâmetros. (Observe que const_castnão permite que uma função altere seu parâmetro, permite passar esse parâmetro para outras funções que não modificam seus parâmetros, mas esqueceram a constanotação.) Também é útil em funções / loop / etc, pois ajuda a entender muito o da mesma maneira que um loop invariável.

  • constdocumenta sua intenção no compilador. Encontrar erros no tempo de compilação é sempre melhor do que esperar a execução desse trecho de código.

  • consté necessário para o polimorfismo seguro do tipo. Ponteiros (em todas as suas formas, não apenas ponteiros brutos) são apenas covariantes se forem const(Nota: não o mesmo que "ponteiro para const"). A covariância requer uma interface somente leitura e a contravariância requer uma interface somente gravação.

A segunda delas eu aprendi primeiro. Comecei constapenas com o destino dos parâmetros de ponteiro e referência, até começar a ver os benefícios de detectar erros mais cedo e começar a usá-lo em locais, etc.

Aprendi então que a maioria dos #defines pode ser substituída (em C ++) por constantes globais, com benefícios adicionais de segurança de tipo. Então eu usei lá também.

Finalmente, participei de uma aula sobre sistemas de tipos e cálculo lambda, e aprendi que conste não- consttipos são fundamentalmente diferentes (já que eles suportam operações diferentes) e, desde então, nunca pensei em escrever código C ++ sem usar muito const.

Ben Voigt
fonte
1

Aqui estão os meus 5 centavos do que eu não vi outros mencionarem. Ao passar por variáveis, você não deseja passar por valor, a menos que realmente precise, para evitar construções e destruições e cópias extras. Portanto, a menos que você realmente precise passar por valor, o uso de referências em todos os lugares, mesmo que você não queira alterar o valor passado, é um aumento significativo no desempenho. Por esse motivo, quando você tem funções que fazem referências a todos os argumentos, é necessário informar ao chamador o que a função não modificará.

É o mesmo princípio, mas eu só queria acrescentar uma razão prática do uso de const.

Nikiforos Rotas
fonte