Quais práticas C # devem ser evitadas em C ++?

45

Atualmente estou ensinando a mim mesmo C ++. Eu sou muito proficiente em c # e queria saber quais práticas comuns em c # podem levar a dificuldades em C ++ e o que um programador de C ++ deve fazer em vez disso.

    
por Donny V. 15.02.2011 / 19:55
fonte

11 respostas

48
  • O primeiro e mais importante, você deve aprender RAII: Aquisição de recursos é inicialização

  • Certifique-se de usar new , então não se esqueça de usar delete em seu programa. Não misture new com malloc e delete com free . new e malloc não são intercambiáveis, nem são delete e free . Como no C #, você não escreve o destruidor (geralmente), então em C ++ você precisa aprender a usar o destructor efetivamente para liberar memória e outros recursos! Depois de conhecer esses conceitos, tente projetar as coisas de maneira RAII para lidar com os recursos com eficiência, para que você não precise lidar com new e delete explicitamente em seu código em todos os lugares.

  • Deve aprender o que é pontos de sequência , comportamento indefinido , comportamento não especificado , comportamento definido pela implementação em C ++. Como o C # não tem esses conceitos, isso significa que você nunca ouviu esses termos durante a programação em C #, portanto é muito provável que você escreva código C ++ (como a[++i]= i , i+=++i ) cujo comportamento é não bem definido. Então, eu recomendo que você leia estes tópicos:

  • Leia itens de Effective C ++ Series por Scott Meyers. Depois deles, leia também Exceptional C ++ Series de Herb Sutter.

PS: Já que falei sobre novo, delete, memória bruta, etc, então deixe-me adicionar uma diferença interessante entre C ++ e C #:

Em C ++, this é um ponteiro, enquanto em C # this é uma referência!

    
por 15.02.2011 / 19:58
fonte
18

O mais fundamental é, claro, relacionado à falta de um coletor de lixo:

don't use new any more than necessary. Understand the RAII idiom: allocate your objects on the stack (without using new), and let their destructors take care of cleaned up allocated memory for you. Or use smart pointers to handle some of this for you.

Além disso, eu diria que há alguns problemas de estilo que você deve se acostumar. C # ainda é, apesar de seu flerte com programação funcional, uma linguagem OOP.

O C ++ é uma linguagem multi-paradigmática e, no C ++ moderno, a OOP não desempenha um papel muito importante. Você deve definitivamente olhar para programação genérica, no entanto. Entenda como usar o STL (as estruturas de dados, iteradores e algoritmos na biblioteca padrão). E sinta-se um pouco sujo quando você escreve uma função virtual.

    
por 15.02.2011 / 20:03
fonte
16

Gerenciamento automático de memória e coleta de lixo é provavelmente algo que você poderia estar perdendo em C ++. Mas IMHO o que você mais sentirá falta é a consistência do .NET framework, onde você tem dado muitas coisas como garantidas, simplesmente porque elas estão embutidas no BCL.

    
por 15.02.2011 / 19:56
fonte
13

O maior problema que já vi é a tendência para novos objetos em todo o lugar e usá-los no heap. Claro, eles podem tomar muito cuidado ao excluí-los, pois não há GC, mas o problema é alocar a pilha em primeiro lugar. C ++ funciona melhor colocando coisas na pilha e copiando. Se você ainda precisar de um único objeto compartilhado, use shared_ptr para contê-lo.

Lembre-se, isso não é exclusivo dos desenvolvedores de C #, eu vi alguns desenvolvedores da Web fazendo o mesmo tipo de coisa.

    
por 15.02.2011 / 20:01
fonte
10

A coleta de lixo é grande, mas se você usar ponteiros inteligentes, poderá evitar a maior parte dos problemas com isso.

Uma questão mais difundida é a da segurança de exceção. Isso não é tanto um hábito de C # que vai te colocar em problemas, mas a falta de um. Em C #, você obtém segurança com using blocks e finally handlers. C ++ não tem nenhum. O que você tem é uma técnica chamada RAII (aquisição de recursos é inicialização), onde as classes são cuidadosamente projetadas para que seus destruidores limpem as coisas. Portanto, em vez de usar um bloco using para abrir um arquivo, você alocará o objeto de arquivo e o destruidor liberará e fechará o arquivo. Ele cuida de projetar e usar classes dessa maneira, mas uma vez que você forma o hábito, seu código pode ser bastante seguro. É apenas uma abordagem diferente. Em geral, o fato de o C ++ ter uma alocação de pilha de objetos exigirá algum ajuste.

    
por 15.02.2011 / 20:00
fonte
7

RAII é definitivamente um dos principais aspectos do C ++ para aprender. Outros pôsteres descreveram, mas vou acrescentar que é bastante similar ao IDisponível do C #. interface combinada com a palavra-chave .

Desconfie de char e string types em C ++, eles cresceram a partir de muitos anos de experiência (amarga) e existem diferentes tipos. Em C # eles são todos Unicode (eu esqueço a codificação), mas em C ++ um char é geralmente dependente da página de código do sistema. Por exemplo, o Windows em inglês usa uma página de código do Windows 1252 por padrão para programas não-unicode. As páginas de código são difíceis de gerenciar e propensas a erros, então use wchar_t e std::wstring do STL. Também esteja ciente de que o tamanho de char e wchar_t é diferente entre diferentes compiladores. Muitos compiladores C ++ baseados em Linux usam um tamanho de caractere diferente e o conselho é diferente novamente! Consulte link para ver mais info.

Esteja ciente do escopo das variáveis e quando elas serão destruídas. Em geral, é uma prática ruim fazer return new object() , pois o chamador pode não perceber que precisa limpar o valor de retorno.

Evite o uso de ponteiros nus. Em vez disso, use unique_ptr ou shared_ptr     + Use make_shared < > () para criar um shared_ptr. Infelizmente não há unique_ptr equivalente no momento.

Saiba mais sobre semântica de movimento - eles podem ajudar muito com RAII. Eu não estou ciente de um equivalente em c #

Entenda o que é um ponteiro opaco. Se você estiver usando a API do Windows, encontrará muitas delas na forma de HANDLE s.

Desconfie de armazenar listas (por exemplo, std::vector ou std::deque ) de objetos que podem ser herdados, pois isso pode levar a fatiamento onde a parte herdada da classe é cortada, então apenas o tipo declarado é deixado.

    
por 04.01.2013 / 15:21
fonte
6

Esqueça o try- (catch-) finalmente e se acostume a fazer alocação / desalocação de recursos através de construtores / destruidores (RAII).

    
por 15.02.2011 / 20:01
fonte
3

Evite programar em C ++ como se fosse C #, essa é a prática que você deve evitar. Na verdade, aprender a língua, é peculiaridades, as partes boas e é expressões idiomáticas.

    
por 16.02.2011 / 04:41
fonte
1

O mais óbvio seria provavelmente a coleta de lixo como certa. Objetos não referenciados devem ser descartados manualmente em C ++, mas no C # você tem o CG para cuidar deles.

    
por 15.02.2011 / 19:58
fonte
1

Gerenciamento de memória, passando por convenções e ponteiros, embora, se você usar uma biblioteca como o Boost, provavelmente seja um problema menor. No entanto, se você está ensinando a si mesmo, é uma boa idéia não usar nenhuma biblioteca e aprender o básico primeiro.

    
por 15.02.2011 / 19:58
fonte
1

Gerenciamento de memória, observando vazamentos de memória e se acostumando a não ter coleta automática de lixo.

    
por 15.02.2011 / 19:59
fonte

Tags