Estou desenvolvendo um emulador de NES como um hobby, no meu tempo livre. Eu uso C ++ porque é a linguagem que eu uso principalmente, conheço e gosto principalmente.
Mas agora que avancei no projeto, percebo que não estou usando quase nenhum recurso específico do C ++ e poderia ter feito isso em C simples e obtendo o mesmo resultado. Não uso modelos, sobrecarga de operador, polimorfismo, herança. Então o que você diria? devo ficar em C ++ ou reescrevê-lo em C?
Não farei isso para obter ganho de desempenho, isso pode ter um efeito colateral, mas a idéia é por que devo usar C ++ se não precisar?
Os únicos recursos do C ++ que estou usando são as classes para encapsular dados e métodos, mas isso também pode ser feito com estruturas e funções, estou usando new e delete, mas também poderia usar malloc e free, e estou usando herança apenas para retornos de chamada, o que pode ser alcançado com ponteiros para funções.
Lembre-se de que é um projeto de hobby, não tenho prazos; portanto, o tempo e o trabalho extras que exigiriam uma reescrita não são um problema, também podem ser divertidos. Então, a pergunta é C ou C ++?
I use C++ because is the language I use mostly, know mostly and like mostly.
E essa é a resposta para sua pergunta. Você só deve mudar o idioma no meio do projeto quando houver um problema que o seu idioma atual não consiga resolver.I don't use templates, operator overloading, polymorphism, inheritance.
Seria muito mais valioso aprender e usar os conceitos do que mudar para C. Como esse é um projeto de hobby, por que não usar algumas coisas que você nunca usou antes? Você sempre pode iniciar outro projeto em C e aprender o idioma, mas para o seu projeto atual não faz sentido mudar.std::shared_ptr
,std::unique_ptr
,boost::scoped_ptr
,std::vector
,std::deque
,std::map
, etc. Para as funções de retorno de chamada, olhar para o uso de functors, e em C ++ 11, você também pode começar a usar coisas como funções lambda.Respostas:
Você não está usando agora, mas da próxima vez que vazar memória ou obter uma dupla exclusão, você estará implorando para voltar
std::vector<T>
,std::unique_ptr<T, Del>
estd::shared_ptr<T>
, o que pode resolver esses problemas facilmente- quase trivialmente. É o que acontece com todos que usam C sobre C ++, eventualmente, e os mais inteligentes simplesmente não esperam que os erros apareçam antes de passarem.O código que usa
new
edelete
diretamente não pertence realmente ao C ++, ele pertence àquele tipo de meia casa que chamamos de "C com classes". É aí que a linguagem era por volta de 1985. Não é particularmente semelhante a C ++, por volta de 2011. Em toda a probabilidade, onde quer que você aprendeu C ++ simplesmente não ensiná-lo algo muito bem que é, infelizmente, em vez comum- e com uma educação melhor, você faria encontre o uso desses recursos.Especificamente, como listei acima, as estruturas de dados genéricas do C ++ e as classes de gerenciamento de recursos são fundamentalmente muito superiores a tudo o que C tem a oferecer. Se você deseja uma matriz alocada dinamicamente, use
std::vector<T>
. Esse é um caso de uso bastante comum. Se você não os estiver usando, seu código corre um enorme risco de erro desnecessariamente, especialmente relacionado ao gerenciamento de recursos. O C ++ pode garantir a segurança e reutilizar o código de uma maneira que o C nunca possa tocar.No entanto, acho que você também pode estar esperando demais. Escrever modelos e sobrecargas de operador não é comum para os consumidores da biblioteca. Se o seu código usar
std::vector<T>
, você não precisará escrever um modelo para que isso aconteça. Se seu código usastd::string
, ninguém está forçando você a sobrecarregar seus operadores. Você só precisa fazer essas coisas para escreverstd::vector<T>
estd::string
- mas ainda pode tirar proveito delas.O polimorfismo / herança também possui apenas um caso de uso específico. Se o seu código não exigir que você escreva nenhum modelo ou use funções virtuais, ele não o fará, e existem programas ou segmentos de programas nos quais você não precisa escrever seus próprios modelos.
Além disso, não há ganho de desempenho em C sobre C ++.
fonte
make_shared
existe, e você pode escrever ummake_unique
modelo trivial que faz o mesmo trabalho. É mais seguro.make_shared
é mais eficiente. Somente as funções de fábrica podem oferecer segurança de exceção garantida.Mesmo se você não usar recursos específicos do C ++, um compilador C ++ detectará mais problemas do que um C devido ao sistema de tipo mais estrito do C ++.
fonte
Eu olhava para isso de outra direção. Você ganhará algo reescrevendo o código em C? Mesmo em um projeto puramente hobby, há um custo associado a uma reescrita como essa. Se nada mais existir, suponho que seria chamado de custo de oportunidade - ou seja, as outras coisas que você poderia ter feito naquele tempo se não estivesse
perdendo temporeescrevendo-o em C.Conclusão: a menos que você ache que o código provavelmente será usado em algum ambiente em que o acesso ao C ++ seja realmente limitado (ou inexistente), seria uma perda de tempo inútil, na melhor das hipóteses. Pelo menos na minha experiência, isso geralmente vai muito além disso muito rapidamente - pensando no código que eu escrevi em C ++ que tinha que ser convertido em C, eu me lembro claramente que mesmo em alguns casos em que parecia deveria ser trivial, eu estava usando muito mais recursos específicos para C ++ do que eu percebi inicialmente. Para ter muita esperança de ser útil, você precisa segmentar o C89 / 90, caso em que você rapidamente se lembra de coisas como ter que definir todas as variáveis no início de um bloco, em vez de onde elas realmente estão. usava.
Em resumo, a menos que você tenha certeza de que a reescrita em C trará um benefício real, há quase inevitavelmente coisas muito melhores para fazer.
fonte
Como resposta mais geral:
Não mude para C ++ apenas porque você está usando alguns dos seus recursos mais exclusivos. Um dia, você pode precisar desses recursos e vai bater na cabeça porque está usando C.
fonte
Para o desenvolvimento hobby, eu consideraria voltar às linguagens simples C. C e C têm mais probabilidade de serem suportadas em pequenos módulos de desenvolvimento hobby.
Muitas das respostas aqui podem ser de tipos profissionais de software. Como um hobby, você não estará codificando continuamente ou em período integral. Portanto, considere em qual idioma você provavelmente se lembrará ou esquecerá as peculiaridades, se você apresentar seu projeto por um ano e depois voltar e tentar ler seu código depois de ficar enferrujado na codificação. O C ++, com um conjunto de recursos mais rico, pode levar mais ou menos tempo para readquirir, dependendo do seu estilo de codificação.
fonte
Não é fácil responder às suas perguntas, pois não sabemos se você está trabalhando no projeto para aprimorar suas habilidades específicas de linguagem (C vs C ++) ou para aprimorar outras habilidades de programação (design, resolução de problemas etc.).
"Os únicos recursos do C ++ que estou usando são as classes para encapsular dados e métodos, mas isso também pode ser feito com estruturas e funções". Isso não é verdade.
structs
em C não suporta encapsulamento e não pode conter funções (métodos) - pelo menos não sem o uso de técnicas como ponteiros para funções. Além disso, as funções em C são mais fracas porque não podem ser sobrecarregadas."Estou usando new e delete, mas também posso usar malloc e free, e estou usando herança apenas para retornos de chamada, o que pode ser alcançado com ponteiros para funções". Como deadmg mencionado, o uso direto
new
edelete
em C ++ não é incentivado. Além disso, a herança IMHO (e o GoF) na POO deve ser preferida à composição apenas quando o polimorfismo é necessário. E não acho que seja trivial obter polimorfismo (ligação tardia) em C usando ponteiros para funções.Fora isso, não tentarei convencê-lo de que C ++ é "melhor" que C porque é uma questão de preferência e sempre depende do problema que você está tentando resolver (o uso de recursos OOP para desenvolver seu emulador NES pode ser uma boa ideia).
fonte
structs
de fato, em C pode ser usado para encapsular métodos. Você simplesmente cria uma estrutura de ponteiros de função e inicializa-os para apontar para as funções que desejar. Veja lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 para obter um exemplo.printf
), mas, ao fazer isso, você perde qualquer verificação de tipo. Não há como ter um conjunto finito de declarações aceitáveis: é 1 (e você obtém a verificação de tipo) ou "muitos" (e perde toda a verificação de tipo, com grande risco pessoal). Como na maioria das coisas em C, é possível, mas geralmente desconfortável.Eu sou muito iniciante, então aqui estão meus 2 bits.
Estou aprendendo C e C ++ no Wibit.net com alguns bons tutoriais básicos em vídeo, talvez eles possam ajudar muito a ter uma visão geral da "situação" (não um anúncio!)
Eu aconselho você a mudar para C, apenas para aprender, como você é um hobby, isso será um prazer, não um problema.
Eu aconselho mais. Faça nos dois idiomas. Compare a maneira e as soluções que você encontrará e usará. Tenho certeza de que não será "tão fácil" como você espera ... mas com certeza você aprenderá muito!
fonte
Aqui estão os prós e contras de C ++ vs. C:
fonte