Por que eu aprenderia C ++ 11, conhecendo C e C ++? [fechadas]

28

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?


fonte
3
Entendo que não deveria haver um discurso sobre C ++ 11 neste fórum e concordo totalmente com isso: todo desenvolvedor tem o direito de ter seu gosto pessoal em relação às ferramentas e linguagens de programação. Existe, no entanto, um problema muito mais prático para mim: eu sou desenvolvedor de C ++ e não gosto de C ++ 11, serei forçado a usar C ++ 11 ou estar fora do mercado / mudar para outro idioma dentro alguns anos?
Giorgio
Bem, eu pensei um pouco sobre isso, é claro que existem linguagens mais modernas do zero, como a linguagem de programação D ou Go. Eles podem ser adequados para o domínio do problema, mais fáceis, mais consistentes, etc. No entanto, a participação de mercado .. nenhum dos principais players do setor oferece suporte a D e até Go parece ser um dos "experimentos" do google. Portanto, a motivação por trás do C + +11 devem ser as melhorias úteis que permitem escrever um código melhor legível, mais seguro e mais rápido, além do amplo suporte do setor.
Nils
@giorgio, nos últimos dois anos, parei de usar C ++ tanto quanto antes (principalmente por perceber o quão religiosos são os fãs de C ++, lendo as respostas a essa pergunta), mas ainda assim também trabalhei em uma biblioteca C ++ que voluntariamente usado C ++ 11 para. Minha experiência foi a seguinte: o C ++ 11 aborda muitos cantos ruins do C ++, e isso é admirável e de fato melhora. Do jeito que faz, ele tem seus próprios cantos ruins (veja o post original não editado). No entanto, esses cantos ruins parecem estar fora do caminho se você fizer as coisas "da maneira normal" (por exemplo, não armazene um lambda para uso futuro).
@ Giorgio, o que eu quero dizer é que o C ++ 11 pode parecer ruim no começo, na verdade o C ++ parece terrível, mas se você concorda com o C ++, provavelmente também gostaria do C ++ 11. Evite tocar em suas partes ruins e você poderá realmente se divertir.
@anon: Uma maneira de se livrar das partes ruins de um idioma é cortar com o passado e iniciar um novo idioma, como a Apple está fazendo com o Swift (para citar apenas um dos inúmeros exemplos). A interface com o código legado pode ser feita por meio de compilação separada. O problema com o C ++ é que ele é estendido indefinidamente, provavelmente porque é suportado por uma comunidade de fãs que acreditam religiosamente que o C ++ é a única linguagem verdadeira. Resumindo: achei o C ++ 03 um pouco ruim, mas o trabalho foi feito, especialmente graças a bibliotecas como Qt e boost. Por outro lado, vou manter minhas mãos longe do C ++ 11.
Giorgio

Respostas:

24

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.

Timmah
fonte
3
Se você é um desenvolvedor de "C / C ++" e se o seu chefe pede para você usar o C ++ 11, você não deve simplesmente adicionar isso ao seu arsenal? Concordo que você não deve gastar todo o seu tempo aprendendo idiomas apenas para aprendê-los, mas quando seu chefe diz: "Aprenda isso", provavelmente é uma boa idéia seguir em frente e aprendê-lo. Também o torna mais comercializável, em vez de precisar explicar no seu próximo aplicativo que você foi demitido por insubordinação.
Panzercrisis 9/07
Haskell ... Engraçado, por causa da inclusão lenta de lambdas em C ++. : P
rbaleksandar
85

É 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 antigo 0. É seguro para o tipo e não é convertido quando não deveria 0. É uma coisa boa que nullptrnão se converte em um int. Não faz sentido que isso aconteça. Você sabe o que o Comitê C ++ encontrou ao tentar considerar #define NULL nullptr? Coisas como char c = NULL;. Quão terrível é isso? A única razão pela qual há uma exceção aqui é porque boolé considerado um tipo integral, o que é bastante errado - mas isso já existia no C ++ e no C. O fato de nullptrnã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_ptre shared_ptrsão muito melhores do que o que estava lá antes, é impossível argumentar que o C ++ 03 maneira era melhor.

#define adding_func(x, y) ((x)+(y))

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

#define add_twice(x) (x + x)

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.

Então você se abre para um mundo de comportamento indefinido para usar variáveis ​​externas cujos escopos já estão concluídos.

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.

Veja C, por exemplo. Depois de tantos anos, ainda há muitas pessoas aprendendo e escrevendo código em C. Por quê?

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.

Se você usar C ou o estilo antigo C ++, não encontrará muitas exceções.

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.

DeadMG
fonte
7
> O fato de o nullptr não converter é bom, é ótimo e você deve amá-lo. OK, sua opinião, mas acalme-se um pouco sobre o que alguém mais deveria AMAR, por favor ... O próximo passo é o talibanismo dos advogados de C ++!
Emilio Garavaglia
5
Penso que a parte posterior da sua resposta é mais sobre por que C ++ deve ser preferido em relação a C. Isso está fora de questão. "As bibliotecas C não são seguras" - como diabos isso responde à pergunta? Quero dizer, é claro que se deve aprender os novos recursos que o C ++ 11 oferece, mas C e C ++ NÃO são feitos para fazer as mesmas coisas. Se C ++ é uma droga para implementar em nível baixo, o mesmo acontece com C #, Java, Python e outros enfeites, porque eles não foram projetados para executar tão baixo. Só porque o C ++ compila no código nativo não significa que você pode usar o OO e a página associada a ele para código crítico no nível do kernel.
yati sagade
11
@ Shahbaz, é claro que você precisa aprender um pouco mais sobre linguagens de programação (por exemplo, sistemas de tipos, escopo lexical etc.), todos os seus comentários estão totalmente fora de sincronia. Comece com este livro: amazon.com/Theories-Programming-Languages-John-Reynolds/dp/…
SK-logic
5
@yati: C ++ possui o mesmo sistema de módulos que C. As funções de membro são implementadas como funções C simples e antigas. As funções virtuais são implementadas da mesma forma que as funções de carregamento de uma DLL. Não há nada debatendo sobre isso. E sim, isso definitivamente se aplica. Para começar, sua crença de que o Unix é o melhor é subjetiva. Sua participação de mercado de 5% sugere o contrário. E segundo, mesmo se eu adorasse o Unix sem fim, um exemplo não definiria uma tendência. O mesmo se aplica aos outros exemplos que você cita. Que exemplos? Eles não têm sentido. C ++ é tão adequado para procedimentos quanto C é.
111311 DeadMG
8
@yatisagade C ++ é uma linguagem de múltiplos paradigmas que não impõe funções virtuais para tudo, e meus programas em C ++ são semelhantes. Partes dele usam design orientado a objetos, partes funcionais etc., dependendo do que resolve melhor esse subproblema específico. Aprecio o C ++ por adicionar o estilo orientado a objetos e o C ++ 11 por expandir bastante o suporte à programação funcional.
11604 David Stone
29

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.

DXM
fonte
7
@ Shahbaz - Eu acho que você ainda está perdendo a intenção de por que funções sem nome foram adicionadas. E "usar variáveis ​​sem tomá-las como entrada" é chamado de encerramento e está disponível em muitos outros idiomas de alto nível. Se você escrevesse muitos códigos de modelo com objetos functor, com o C ++ 11 você estaria recebendo funções lambda de braços abertos. Pense desta maneira ... quando o compilador gera código de máquina, não existe função ou classe de modelo. Todos eles são "instanciados" para criar classes / funções concretas antes desse ponto. Lambdas são a mesma coisa quando se trata de stateful ...
DXM
5
... functores. Em vez de fazer com que as pessoas escrevam uma tonelada de código, um para cada tipo de functor e cada elemento de fechamento que você deseja transmitir, o C ++ 11 permite especificar uma sintaxe de atalho e instanciará automaticamente uma instância inteira de functor interno, exatamente como instancia modelos. Novamente, lembre-se de que a maioria desses recursos não será usada em 98% do código no nível do aplicativo, mas eles foram adicionados para tornar as bibliotecas como STL / Boost muito mais poderosas e fáceis de implementar / manter / depurar
DXM
10
@ Shahbaz: Ok, você não entende as funções ou fechamentos lambda. Que é razoável. O fato de serem usados ​​em vários idiomas diferentes deve sugerir que são úteis, se você os entende ou não, e que você deve entendê-los antes de criticá-los demais.
9309 David Thornley
8
@ Shahbaz: Se você acha que os fechamentos são semelhantes às variáveis ​​globais, não entende os fechamentos. (Dica: variáveis ​​globais causam problemas porque qualquer função pode modificá-las.) Se você entendesse o conceito de lambdas, não a implementação, não o atribuiria à confusão de classes versus código. Tudo no padrão C ++ existe por motivos convincentes para um grande número de pessoas inteligentes. Você não precisa concordar com os motivos, mas sem conhecê-los, está criticando por ignorância.
precisa
6
@ Shahbaz, não há absolutamente nenhuma semelhança entre fechamentos e globais, você está perdendo completamente o objetivo. Leia isto: en.wikipedia.org/wiki/Lambda_calculus e exploda seu cérebro: en.wikipedia.org/wiki/Combinatory_logic
SK-logic
18

É tão difícil escrever uma função que você precisa escrever o conteúdo da função em linha com o código, além de não dar nome a ela?

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

Bem, por que você simplesmente não escreve o código lá em vez de torná-lo uma função lambda?

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.

#define added_func (x, y) ((x) + (y))

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.

template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs)
                -> decltype(lhs+rhs) {return lhs + rhs;}

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.

alto e claro
fonte
Argumentos sobre auto-documentação e menos rolagem, etc, tenho certeza de que argumentos opostos, como "código de confusão", "restrição de acesso", etc. foram usados ​​para argumentar por que funções fora da classe devem ser proibidas. Acho que as pessoas precisam ter mais experiência para decidir qual é o melhor. Parece-me que este é um experimento fracassado ou um projeto ruim. Estou mais convencido de não ser o rato de laboratório neste experimento.
Shahbaz
Sobre a sintaxe que parece feia, considere estes dois por exemplo: bool is_alive;e bool 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.
Shahbaz
3
bonito! = bonito e ruim! = ruim.
DeadMG
@ Shahbaz: Eu acho que lambdas são ótimos conceitos (e existem há muitos anos em linguagens como o Lisp). Eu os uso muito em Haskell. Tenho menos certeza de que eles se encaixam em linguagens como C ++, Java etc. Eles parecem um pouco depois: algo que foi adicionado mais tarde porque as lambdas se tornaram populares. Por que eles não foram introduzidos nessas línguas desde o início? Stroustrup e Goslin nunca ouviram falar de Lisp?
Giorgio
8

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.

Emilio Garavaglia
fonte
Eu também concordo. E, como desenvolvedor, acho muito perturbador ter uma linguagem que muda constantemente (que eu tenho que aprender várias vezes). Se você desenvolver um novo idioma, deve começar de novo e usar um nome diferente. Se você deseja que ele coopere com o código legado, há uma compilação separada para isso. Então, eu realmente não entendo a política de alterar um idioma existente incorporando os recursos mais recentes que se tornaram moda. Como alguém disse: um maior desenvolvimento não implica automaticamente progresso.
Giorgio
"C ++ simplesmente não pode ser simplificado nesse sentido. Não nessa idade.": Por que outras linguagens de programação (por exemplo, C, Ada, ...) não seguem o mesmo caminho? Talvez porque eles tenham seu próprio nicho de aplicativos e não se espere que eles sejam a ferramenta para todas as áreas de aplicativos possíveis.
Giorgio
@ giorgio: sim ... você provavelmente está certo no sentido "pragmático". Mas, em teoria ... Lembro-me de alguns bons dias em que pascal era a "linguagem de referência de ensino" e ada era a "aspirante a tudo em linguagem de programação".
Emilio Garavaglia
Eu também aprendi programação em Pascal. Até onde eu sei, Ada passou por várias revisões, mas o design básico da linguagem não foi subvertido. O mesmo com C e Pascal. Se alguém deseja desenvolver uma linguagem realmente nova, deve ser corajoso o suficiente para fazer um corte claro e começar algo novo, como D, Java, C #. Meu problema com o caminho atual que o C ++ está tomando é que ele (desnecessariamente) está ficando muito complexo. Se os princípios KISS e YAGNI se aplicam ao design de software, por que eles não deveriam se aplicar também ao design de linguagem de programação?
Giorgio
@Giorgio: oh ... eles se aplicam ... exatamente como você disse. Se você acha que C # ou D fez uma escolha melhor do que um C ++ "fervido" (minha interpretação do seu sentimento), basta usá-los em vez de C ++. À medida que o tempo passa, o C ++ morre lentamente. No momento, vejo o C ++ 11 dando uma nova chance ao C ++ 03 "fervido" e D com ainda algo faltando para quebrar a barreira inicial. Os interesses econômicos e corporativos também desempenham um papel na maneira como o desenvolvimento é financiado e incentivado. Você está certo na teoria, mas o mundo real é mais complexo.
Emilio Garavaglia
7

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.

Nemanja Trifunovic
fonte
6

Depois de tantos anos, ainda há muitas pessoas aprendendo e escrevendo código em C. Por quê? Porque a linguagem é boa.

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.

Dima
fonte
Você citou minha frase incompletamente. Como eu disse na sentença seguinte, goodsignifica 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).
Shahbaz
1
@ Shahbaz: Eu citei frases completas. Você fez uma conexão causal, e eu disse que ela é, na melhor das hipóteses, incompleta. Felizmente, não estudo mais. :) Eu já fiz bastante disso. Eu moro nos EUA e, quando fui para a faculdade (há mais de 15 anos), C era a língua introdutória. No entanto, hoje a maioria das escolas norte-americanas começam com Java, e não há que muitos jovens programadores que conhecem C.
Dima
5
@ Shahbaz: Realmente não vejo o problema de as regras de linguagem terem exceções. Sim, C é uma linguagem muito mais simples que C ++. Por outro lado, o C ++ facilita a escrita de códigos mais simples. Para escrever um código mais simples, você precisa de mais recursos de idioma. Isso torna a linguagem mais complexa. Eu, por exemplo, gosto de coisas como classes, referências, RAII, modelos, construtores, destruidores, exceções e espaços para nome. Mas você disse que sua pergunta não era sobre C vs C ++, então não escrevi sobre isso na resposta.
Dima
5
  • Assembly foi criado porque as pessoas não gostavam de escrever código de máquina
  • C foi criado porque as pessoas não gostavam de escrever montagem
  • C ++ foi criado porque as pessoas não gostavam de escrever C
  • O C ++ 11 foi criado porque as pessoas não gostavam de escrever C ++

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.

Pubby
fonte
Todos os idiomas foram criados porque alguém não gostou dos existentes. Isso não faz nenhum deles bom.
Shahbaz
Eu não digo que NULLdeveria ser um int. 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.
Shahbaz
2
"O C ++ 11 foi criado porque as pessoas não gostavam de escrever C ++": se não gostavam de escrever C ++, por que o C ++ é um subconjunto do C ++ 11?
Giorgio
1
Deveria ser: C # e Java foi criado porque as pessoas não gostavam de escrever C ++.
Calmarius 10/09/12
4

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.

littleadv
fonte
4

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.

Nir Friedman
fonte
E também, a propósito, eficiente.
Nir Friedman 10/10