Sou programador em C e C ++, embora não me atenha a nenhuma das linguagens e escreva uma mistura das duas. Às vezes, ter código em classes, possivelmente com sobrecarga de operador ou modelos, e o ótimo STL é obviamente uma maneira melhor. Às vezes, o uso de um ponteiro simples da função C é muito mais legível e claro. Então, encontro beleza e praticidade nos dois idiomas. Não quero entrar na discussão de "Se você os mistura e compila com um compilador C ++, não é mais uma mistura, é tudo C ++". Acho que todos entendemos o que quero dizer com mistura. Além disso, não quero falar sobre C vs C ++, esta questão é sobre C ++ 11.
O C ++ 11 apresenta o que eu acho que são mudanças significativas na forma como o C ++ funciona, mas introduziu muitos casos especiais, exceções e irregularidades que alteram o comportamento de diferentes recursos em diferentes circunstâncias, colocando restrições à herança múltipla, identificadores que agem como palavras-chave, extensões de literais de string, captura de variável de função lambda, etc.
Eu sei que em algum momento no futuro, quando você disser C ++, todos assumirão o C ++ 11. Assim como quando você diz C hoje em dia, você provavelmente quer dizer C99. Isso me faz pensar em aprender C ++ 11. Afinal, se eu quiser continuar escrevendo código em C ++, em algum momento talvez precise começar a usar esses recursos simplesmente porque meus colegas o fizeram.
Veja C, por exemplo. Depois de tantos anos, ainda há muitas pessoas aprendendo e escrevendo código em C. Por quê? Porque a linguagem é boa. O que significa bom é que, segue muitas das regras para criar uma boa linguagem de programação. Portanto, além de ser poderoso (fácil ou difícil, quase todas as linguagens de programação são), C é regular e possui poucas exceções, se houver. C ++ 11, no entanto, acho que não. Não tenho certeza de que as alterações introduzidas no C ++ 11 estejam melhorando a linguagem.
Portanto, a pergunta é: Por que eu aprenderia C ++ 11?
Respostas:
Você deve aprender se achar que precisará conhecê-lo no futuro para conseguir um emprego. Se você tiver certeza de que permanecerá comercializável na força de trabalho como um C / C ++ [e o que mais você saiba], não o aprenda. Se o seu chefe lhe disser para usar o C ++ 11, diga "não, eu não faço isso". Se ele te despedir, vá trabalhar em outro lugar. Aprenda C ++ 11 quando prever que em breve não conseguirá um emprego satisfatório com as habilidades que conhece atualmente.
Queria esclarecer minha lógica: não sou anti-C ++ 11. Apenas dizendo que você pode generalizar a pergunta do OP para "Por que eu deveria aprender X". Eu nunca aprendi ML, esquema ou haskell porque tenho um emprego em C e C ++. Tenho certeza de que esses idiomas são úteis para alguém, mas não são benéficos para mim aprender agora. Se alguém me ofereceu um bom dinheiro para programar em ML, eu poderia tentar aprender.
fonte
É simples. O C ++ 11 torna o código muito mais fácil, mais limpo de escrever e mais rápido.
nullptr
é uma melhoria VAST em relação ao antigo0
. É seguro para o tipo e não é convertido quando não deveria0
. É uma coisa boa quenullptr
não se converte em umint
. Não faz sentido que isso aconteça. Você sabe o que o Comitê C ++ encontrou ao tentar considerar#define NULL nullptr
? Coisas comochar c = NULL;
. Quão terrível é isso? A única razão pela qual há uma exceção aqui é porquebool
é considerado um tipo integral, o que é bastante errado - mas isso já existia no C ++ e no C. O fato denullptr
não converter é bom , é ótimo e você deve adorar.Ou o que dizer de referências a rvalores e modelos variados? Código mais rápido e genérico. É uma vitória total ali.
E as melhorias na biblioteca? Coisas como
function
,unique_ptr
eshared_ptr
são muito melhores do que o que estava lá antes, é impossível argumentar que o C ++ 03 maneira era melhor.Nem remotamente equivalente. As macros são ruins por seis bilhões de razões. Não vou citar todos eles aqui, mas é sabido que as macros devem ser evitadas para praticamente todos os propósitos pelos quais possam ser evitadas. O que você vai fazer quando for
Oh espere, espero que você não tenha incrementado ou algo assim
x
. A qual a versão da função de modelo é totalmente imune. Espero também que você não aprecie os espaços para nome , por exemplo.Em uma API funcional, por exemplo, algoritmos STL, a referência é adequada. Se for um retorno de chamada armazenado, será necessário capturar por valor. Qualquer documentação que você tenha sobre a função deve indicar claramente o que é necessário. O fato de o código ser escrito em um lambda é irrelevante para o problema de se referir a variáveis locais - se você passar um objeto de função regular, terá exatamente o mesmo problema. E não é um problema. Em absoluto. Porque é inerentemente óbvio quando você pode e não pode se referir a variáveis locais.
Há muitas pessoas que não escovam os dentes pela manhã. Existem muitos assassinos, estupradores e prostitutas. E políticos. Pessoas que cometem suicídio. Você argumentaria que isso torna essas atividades boas ou úteis? Claro que não. É uma falácia lógica que, só porque alguém fez isso, deve ser boa ou útil.
O C ainda está sendo escrito por três razões: porque o C ++ é uma droga para implementar, por exemplo, no modo incorporado ou no kernel; porque as bases de código herdadas são escritas em C e custariam muito para atualizar, embora isso seja questionável, dada a excelente interoperabilidade de C do C ++; e porque as pessoas que escrevem não sabem como programar. É isso aí. Não há outro motivo para escrever C.
E as matrizes patéticas no estilo C, para um exemplo simples? O número de pessoas que não conseguem obter arrays e ponteiros na cabeça é obsceno. Sem mencionar o fato de que a biblioteca C Standard é incrivelmente insegura.
Seus argumentos principais estão cheios de falácias e mal-entendidos lógicos.
fonte
C ++ 11 não é uma nova linguagem; é apenas uma extensão / modificação do C ++ que você já conhece. O C ++ 11, como qualquer outra linguagem de programação, consiste em recursos. Muitos deles estavam lá antes, alguns deles são novos. Mas sua pergunta realmente é: devo aprender todos os recursos da linguagem (neste caso, C ++ 11), ou apenas me familiarizar com 90% dela?
IMO, mesmo que você não esteja usando todo o idioma, leia pelo menos o que os novos recursos fazem por você. Muitos deles foram introduzidos para tornar o código da biblioteca / estrutura (especialmente modelos) mais fácil de escrever (por exemplo, antes que o encaminhamento perfeito do C ++ 11 fosse impossível), mas se você nunca precisou desses recursos antes, é possível que ganhe observe que esses recursos foram adicionados no C ++ 11.
Por outro lado, se você já se interessou em escrever código de biblioteca / núcleo que imita algumas das funcionalidades do STL / Boost e se viu limitado pelo idioma, você chegou a 95% de ter uma solução muito legal e elegante, mas depois você foi interrompido porque descobriu que a linguagem simplesmente não suporta o que deseja, você perceberá o poder realmente impressionante do C ++ 11. Desde que nossa equipe atualizou para o VS2010 (e descobrimos o Boost no processo), eu pude criar um código incrível, que seria simplesmente impossível antes de coisas como referências de valor r e encaminhamento de parâmetros de modelo.
Também coisas como lambda podem parecer estranhas, mas não introduzem uma nova construção. Em vez disso, eles tornam o que tínhamos antes muito mais fácil de escrever. Anteriormente, cada função lambda teria que ser uma classe separada. Agora é apenas {... código ...}. Adoro.
A chave é não olhar para esses recursos e pensar em como a lista é assustadora. Em vez disso, use C ++ como de costume e quando encontrar algum cenário em que esses novos recursos do C ++ 11 sejam úteis (mais de 90% das pessoas nunca chegarão a esse ponto), ficará muito feliz que a extensão para o idioma foi feito. Por enquanto, sugiro que você aprenda o suficiente sobre o idioma para saber o que está lá, não necessariamente como usá-lo.
fonte
Ao fazer isso, role para cima ou abra um novo arquivo de origem e adicione a definição da função. Então você tem que voltar e continuar o que estava trabalhando, o que o distrai até certo ponto.
Fora isso, quando outras pessoas estão lendo seu código, um lambda pode ser mais auto-documentado em alguns casos, em vez de dizer "Ah, o que essa função faz?" e, saltando para a declaração, você pode apenas dar uma olhada no que está fazendo em seu próprio lugar.
Há uma boa conversa de Herb Sutter sobre lambdas, talvez ele possa convencê-lo melhor:
http://channel9.msdn.com/events/PDC/PDC10/FT13
Porque você não pode fazê-lo quando estiver usando algoritmos STL ou qualquer função que esteja usando que exija que você passe uma função.
Não há como justificar esse uso em vez de lambdas, você não pode preencher seu código com macros em todos os lugares. Macros e funções têm finalidades diferentes, e uma, em geral, não substitui a outra.
Eu concordo, isso é feio. No entanto, lembro-me de dizer "por que diabos devo descobrir o tipo dessa expressão, mesmo que o compilador possa inferir isso?" em muitos casos. Isso pode ajudar muito nesses momentos.
Resumindo:
Embora os novos recursos do C ++ 11 pareçam feios em sua sintaxe, acho que podemos nos acostumar com eles em pouco tempo. Todo novo construto de linguagem é difícil de aprender a princípio; imagine a primeira vez que você aprendeu a escrever uma classe inteira: Colocando a declaração no arquivo de cabeçalho, sem esquecer o ponto-e-vírgula extra no final, colocando as definições no arquivo de origem, incluindo o arquivo de cabeçalho, garantindo uma proteção para evitar inclusões múltiplas, sem esquecer o operador de resolução do escopo nas declarações da função membro e assim por diante ...
Mas tenho certeza de que, depois de escrever algumas aulas, você se acostuma e não pensa na complexidade desse processo: porque você sabe que uma classe facilita muito o seu trabalho como programador e o utilitário que você ganhar com essa nova construção é muito maior que a perda de utilidade durante o tempo em que você estava tentando aprender o idioma . Eu acho que essa pode ser a razão pela qual se deve tentar aprender ou usar o C ++ 11 de maneira semelhante.
fonte
bool is_alive;
ebool thisSpecialObjectOfMineIsAlive;
. Ambos fazem o mesmo, mas o segundo parece realmente feio. Por quê? Porque pensei erroneamente que colocar mais informações torna isso mais claro, mas fez o oposto. É o mesmo negócio aqui, Stroustrup foi bom ao nos dar recursos, mas ele simplesmente não ficou bonito. Para mim, isso mostra um design ruim.Na verdade, o OP tem alguns pontos, como a maioria das respostas. Mas eles são "distantes" na visão. O C ++ (incluindo o subconjunto C) tem uma longa história em que vários recursos foram adicionados ao longo do tempo, alguns deles usados com mais ou menos frequência e, através de sua utilização e erros, aperfeiçoados em outros e em outros.
Às vezes acontece que, após a introdução de um novo recurso, um antigo é mais necessário ou se sente em contradição com ele. Uma linguagem "limpa" deve ser autoconsistente e não devem ser removidos os recursos necessários.
Mas adicionar não destrói nada. A remoção (ou alteração) interrompe o código existente que ainda está em produção; portanto, qualquer recurso que você adicionar, você deve tomar cuidado para não quebrar o código existente (em particular, não o interrompa silenciosamente , fazendo-o fazer coisas diferentes conforme o planejado). )
Você tem que aprender tudo isso? Sim, porque todos os recursos são bons ou ruins, mais cedo ou mais tarde. Se isso é bom para a "qualidade" da linguagem (admitindo que existe uma medida objetiva para ela) é outra história: por quanto tempo a compatibilidade com versões anteriores deve ser mantida? difícil encontrar uma resposta, quando alguém diz 3 anos e outro diz 50.
A alternativa para manter o C ++ mais "regular" é ... quebrá-lo com mais frequência, com uma reinicialização automática. Mas não haverá mais C ++.
Existem tentativas de fazer isso também (pense em D, por exemplo: muito mais ortogonal como C ++ (até 11) realmente é)), mas quão populares são elas? Uma das razões de sua dificuldade em ter impulso é a incompatibilidade com muitos códigos existentes que ainda precisam ser executados.
C ++ 11, para mim, é claramente um compromisso entre novas necessidades e compatibilidade com versões anteriores. Isso resultou em uma certa "confusão" de suas especificações e implementação. Até que o custo dessa "bagunça" seja menor que o custo da incompatibilidade ... você precisa sair com esse compromisso.
Se você não aguenta mais, ... é melhor considerar outro idioma mais jovem. C ++ simplesmente não pode ser simplificado nesse sentido. Não nessa idade.
fonte
Mesmo se você decidir ignorar os novos recursos do C ++ 11, você ainda se beneficiará deles porque a Biblioteca Padrão do C ++ os utilizará. Por exemplo, no C ++ 98, ter uma variável do tipo
vector<string>
era potencialmente um desastre de desempenho devido ao número de cópias necessárias para a realização do crescimento do vetor. Com o construtor de movimento C ++ 11, isso não é problema. De fato, eu gostaria que o C ++ 11 nos trouxesse mais novos recursos, não menos - especialmente na Biblioteca Padrão.fonte
Primeiro, a maioria dos estudantes hoje em dia está aprendendo Java ou .NET, e não C. Em segundo lugar, as pessoas ainda usam o C não apenas por causa de suas vantagens como linguagem, mas principalmente porque há uma enorme quantidade de software existente escrito em C que precisa ser aprendido. seja mantido e estendido e, em muitos casos (por exemplo, plataformas incorporadas), um compilador C é tudo o que existe. Aliás, essas são algumas das razões pelas quais as pessoas ainda escrevem COBOL.
É muito raro um programador do setor começar a trabalhar em um projeto novo que não esteja vinculado a uma base de código existente e continuar trabalhando sozinho. Portanto, o motivo para aprender C ++ 11 é que você provavelmente precisará lidar com o código escrito por outras pessoas, que usa os novos recursos. Além disso, os recursos adicionados foram adicionados por um motivo. Depois de aprendê-los e usá-los, você poderá apreciá-los.
fonte
good
significa que ele segue as regras de um bom design de linguagem de programação. Não sei onde você estuda, mas sei de 4 ou 5 países e todos começam a aprender programação com C. Como eu disse, com C, quase não há exceções (algo que é oposto em Java, você mal podia encontre uma construção que não tenha uma exceção).Você chegará a um ponto em sua carreira em C ++ em que se perguntará: "Eu gostaria que os functores fossem mais simples" ou "Por que NULL é um int?" e então você entenderá o C ++ 11.
fonte
NULL
deveria ser umint
. Não deveria. O que não acho adequado é introduzir uma construção na linguagem que resolva isso, mas introduz exceções. Eles deveriam ter conseguido fazer a mesma coisa de uma maneira melhor.Aprender é sempre benéfico. Conhecimento é poder.
Essa é a resposta, basicamente. Tudo o resto são apenas detalhes de como exatamente você pode se beneficiar e de quais poderes você tem ao conhecê-lo, e são tantos que qualquer enumeração seria incompleta.
Um exemplo é sua própria pergunta. Você não seria capaz de perguntar sem aprender pelo menos um pouco.
E como comentei - a verdadeira preocupação não é por que aprender, mas por que usar . E essa é uma pergunta totalmente diferente.
fonte
Você deve aprender C ++ 11 porque os recursos adicionados permitem escrever um código melhor. Algumas pessoas mencionaram a segurança de tipo de ponteiros NULL e lambdas, o que é muito bom. Mas quero chamar a atenção para o que considero a mudança mais dramática no C ++ 11, especialmente em um grande ambiente de produção: mover semântica.
O C ++ 11 suporta noções separadas de 'mover' e 'copiar'. No C ++ regular, apenas temos o operador =, que basicamente faz os dois. Mas, na verdade, estamos expressando duas idéias separadas com um operador, o que é perigoso.
O exemplo mais óbvio de onde isso é útil é o novo unique_ptr. Possui todos os melhores recursos dos antigos auto_ptr e scoped_ptr. Suponha que desejemos ter um ponteiro que seja garantidamente o único ponteiro apontando para um objeto. Como lidamos com a = b? Bem, antes, estávamos estagnados, você poderia proibi-lo completamente (como scoped_ptr) ou poderíamos fazer o que o auto_ptr faz onde a = b rouba a propriedade de b. Esse comportamento do auto_ptr é muito confuso porque a = b realmente muda b. unique_ptr lida com isso: a = b não é permitido, mas você tem a = std :: move (b) para roubar a propriedade. Como isso é útil? Onde, há uma versão separada (sobrecarregada) do swap que usa a semântica de movimentação em vez de copiar a semântica. Isso significa que esse unique_ptr pode ser trocado, sem problemas. Isso significa que unique_ptr, diferente de auto_ptr, é seguro usá-lo em um contêiner e diga ordenar. unique_ptr é basicamente o gerenciamento completo e seguro de toda a memória quando você não precisa de vários ponteiros no mesmo objeto.
Outro ótimo exemplo: suponha que você tenha um objeto que não possa ser copiado. Isso é útil em várias situações. Você nunca pode retornar esse objeto de uma função, porque quando a função termina, ela copia o que você está retornando. O irônico é que geralmente o compilador realmente otimiza isso (ou seja, nada é copiado no final, o valor de retorno é criado no endereço de uma eventual atribuição). Mas isso não tem nada a ver com o motivo de torná-lo impossível de copiar; retornar de uma função é realmente apenas mover o objeto de dentro do escopo da função para fora. Agora você pode escrever objetos que não podem ser copiados, mas SÃO móveis, e esses objetos podem ser retornados das funções.
A semântica de movimentação facilita muito a gravação de código que não vaza e é seguro para threads.
fonte