Usando C ++ pero no usando las características específicas del lenguaje, ¿debería cambiar a C?

16

Estoy desarrollando un emulador NES como hobby, en mi tiempo libre. Uso C ++ porque es el lenguaje que más uso, sé más y me gusta más.

Pero ahora que avancé un poco en el proyecto, me doy cuenta de que no estoy usando casi ninguna característica específica de C ++, y podría haberlo hecho en C simple y obtener el mismo resultado. No uso plantillas, sobrecarga de operadores, polimorfismo, herencia. Entonces, ¿qué dirías? ¿Debo permanecer en C ++ o reescribirlo en C?

No haré esto para ganar rendimiento, podría ser un efecto secundario, pero la idea es ¿por qué debería usar C ++ si no lo necesito?

Las únicas características de C ++ que estoy usando son clases para encapsular datos y métodos, pero eso se puede hacer también con estructuras y funciones, estoy usando new y delete, pero también podría usar malloc y free, y estoy usando la herencia solo para devoluciones de llamada, lo que podría lograrse con punteros a funciones.

Recuerde, es un proyecto de pasatiempo, no tengo plazos, por lo que el tiempo de trabajo y el trabajo que requerirían una reescritura no son un problema, también pueden ser divertidos. Entonces, la pregunta es C o C ++?

Petruza
fuente
3
Me parece que ya te has respondido a ti mismo: ¿por qué usar C ++ si solo necesitas C? Hay muchas situaciones en las que C está perfectamente bien.
Giorgio
3
@Giorgio: Y todos se evaporan después de los primeros sesenta segundos y necesitas mantener tu código.
DeadMG
77
I use C++ because is the language I use mostly, know mostly and like mostly.Y esa es la respuesta a tu pregunta. Solo debe cambiar los idiomas a mitad del proyecto cuando hay un problema que su idioma actual no puede resolver. I don't use templates, operator overloading, polymorphism, inheritance.Sería mucho más valioso aprender y usar los conceptos, que cambiar a C. Dado que este es un proyecto de pasatiempo, ¿por qué no usar algunas cosas que no ha usado antes? Siempre puede comenzar otro proyecto en C y aprender el lenguaje, pero para su proyecto actual no tiene sentido cambiar.
yannis 03 de
44
Tampoco uso el 100% de un idioma en cada proyecto que escribo. Conoces mejor C ++, puedes encontrar buenas razones para usar funciones para las que no has usado antes. Puede empezar a tratar a C ++ como C mucho más seguro, una vez que empiece a usar el material de la biblioteca estándar y construcciones impulsar gusta std::shared_ptr, std::unique_ptr, boost::scoped_ptr, std::vector, std::deque, std::map, etc Para las funciones de devolución de llamada, mirada en el uso de palabras funcionales, y en C ++ 11, se También puede comenzar a usar cosas como funciones lambda.
wkl
3
@Giorgio: Sí. Rodar la lista vinculada infinita está destinado a producir errores innecesarios.
DeadMG

Respuestas:

40

No está utilizando ahora, pero la próxima vez que pérdida de memoria o de obtener una doble eliminación, se le rogando para volver a std::vector<T>, std::unique_ptr<T, Del>y std::shared_ptr<T>, lo que puede resolver esos problemas fácilmente- casi trivial. Eso es lo que les sucede a todos los que usan C sobre C ++, eventualmente, y los más inteligentes simplemente no esperan a que aparezcan los errores antes de pasar.

El código que usa newy deletedirectamente no pertenece realmente a C ++, pertenece a ese tipo de media casa que denominamos "C con clases". Ahí es donde estaba el lenguaje alrededor de 1985. No es particularmente similar a C ++, alrededor de 2011. Con toda probabilidad, donde sea que aprendió C ++ simplemente no lo enseñó muy bien, algo que desafortunadamente es bastante común, y con una mejor educación, lo haría encuentre el uso de estas funciones.

Específicamente, como mencioné anteriormente, las estructuras de datos genéricos de C ++ y las clases de administración de recursos son fundamentalmente masivamente superiores a todo lo que C tiene para ofrecer. Si desea una matriz asignada dinámicamente, úsela std::vector<T>. Ese es un caso de uso bastante común. Si no los está utilizando, entonces su código corre un gran riesgo de error innecesariamente, especialmente relacionado con la gestión de recursos. C ++ puede garantizar la seguridad y el código de reutilización de una manera que C nunca pueda tocar.

Sin embargo, creo que también podrías estar esperando demasiado. Escribir plantillas y sobrecargas de operadores no es común para los consumidores de bibliotecas. Si usa su código std::vector<T>, no necesita escribir una plantilla para que eso suceda. Si usa su código std::string, nadie lo obliga a sobrecargar a sus operadores. Solo tiene que hacer esas cosas para escribir std::vector<T> y std::string, pero aún puede aprovecharlas al máximo.

El polimorfismo / herencia también solo tiene un caso de uso específico. Si su código no requiere que escriba ninguna plantilla o use funciones virtuales, entonces no lo hace, y hay programas o segmentos de programas en los que no necesita escribir sus propias plantillas.

Además, no hay ganancia en el rendimiento en C sobre C ++.

DeadMG
fuente
1
@Giorgio: make_sharedexiste, y puedes escribir una make_uniqueplantilla trivial que haga el mismo trabajo. Es más seguro.
DeadMG
44
Gran respuesta. Clavo en la cabeza. C ++ es más valioso para estas pequeñas bibliotecas que siempre deberíamos estar usando.
Andres Jaan Tack
2
@Giorgio: No es seguro porque al invocar varios argumentos como ese, puede obtener una pérdida de memoria en el caso de una excepción, y make_sharedes más eficiente. Solo las funciones de fábrica pueden ofrecer una seguridad de excepción garantizada.
DeadMG
66
@ tp1: ¿WTF? En inglés por favor.
DeadMG
2
@Lohoris No necesitas una cita para el sentido común. ¿De qué manera debería ser C más eficaz que C ++?
Chris dice reinstalar a Mónica
7

Incluso si no utiliza características específicas de C ++, un compilador de C ++ detectará más problemas que uno de C ++ debido al sistema de tipo más estricto de C ++.

Nemanja Trifunovic
fuente
6

Lo miraría desde la otra dirección. ¿ Ganarás algo reescribiendo el código en C? Incluso en un proyecto puramente aficionado, hay un costo asociado con una reescritura como esa. Si nada más hay lo que supongo que se llamaría costo de oportunidad, es decir, las otras cosas que podría haber hecho en ese momento si no estuviera perdiendo el tiempo reescribiéndolo en C.

En pocas palabras: a menos que piense que es probable que el código se use en algún entorno donde el acceso a C ++ es realmente limitado (o inexistente), sería una pérdida de tiempo inútil en el mejor de los casos. Al menos en mi experiencia, generalmente va mucho más allá de eso muy rápidamente, pensando en el código que he escrito en C ++ que recordar el tuvo que convertirse a C, puedo recordar claramente que incluso en algunos casos en los que parecía debería ser trivial, estaba usando muchas más características específicas de C ++ de lo que inicialmente me di cuenta. Para tener muchas esperanzas de ser útil, tendría que apuntar a C89 / 90, en cuyo caso le recordarán rápidamente cosas como tener que definir todas las variables al comienzo de un bloque en lugar de dónde están realmente usado.

En resumen, a menos que esté bastante seguro de que reescribir en C proporcionará un beneficio real, casi inevitablemente hay cosas mucho mejores que hacer.

Jerry Coffin
fuente
Hace un tiempo tuve que escribir una biblioteca para usarla en otro proyecto en C y pensé que era una buena idea implementarla también en C, hombre, qué idiota tan estúpido era en aquel entonces.
Chris dice que reinstala a Mónica
1

Como respuesta más general:

No cambie a C ++ solo porque está utilizando algunas de sus características más exclusivas. Es posible que un día necesites esas funciones y solo te golpees la cabeza porque estás usando C.

Dinámica
fuente
1

Para el desarrollo de aficionados, consideraría volver a cambiar a los simples C. Los lenguajes C y C tienen más probabilidades de ser compatibles con pequeños módulos de desarrollo de pasatiempos.

Muchas de las respuestas aquí pueden ser de tipos de software profesionales. Como aficionado, no codificará continuamente o a tiempo completo. Así que considere en qué idioma es más probable que recuerde u olvide las peculiaridades dentro, si presenta su proyecto durante un año y luego regresa e intenta leer su código después de haberse oxidado en la codificación. C ++, que tiene un conjunto de características más rico, puede tomar más o menos tiempo para volver a adquirir, dependiendo de su estilo de codificación.

hotpaw2
fuente
1

No es fácil responder sus preguntas, ya que no sabemos si está trabajando en el proyecto para mejorar sus habilidades específicas de lenguaje (C vs C ++) o para mejorar otras habilidades de programación (diseño, resolución de problemas, etc.).

"Las únicas características de C ++ que estoy usando son clases para encapsular datos y métodos, pero eso también se puede hacer con estructuras y funciones". Esto no es verdad. structsen C no admiten la encapsulación y no pueden contener funciones (métodos), al menos no sin utilizar técnicas como punteros a las funciones. Además, las funciones en C son más débiles porque no se pueden sobrecargar.

"Estoy usando new y delete, pero también podría usar malloc y free, y estoy usando la herencia solo para devoluciones de llamada, lo que podría lograrse con punteros a funciones". Como deadmg mencionó, no se recomienda usar directamente newy deleteen C ++. Además, la herencia de IMHO (y GoF) en OOP debe preferirse sobre la composición solo cuando se requiere polimorfismo. Y no creo que sea trivial lograr el polimorfismo (unión tardía) en C usando punteros para las funciones.

Aparte de eso, no intentaré convencerte de que C ++ es "mejor" que C porque es una cuestión de preferencia y siempre depende del problema que estés tratando de resolver (podría ser útil usar las características de OOP para desarrollar tu emulador NES) una buena idea).

sakisk
fuente
1
structsen C puede, de hecho, usarse para encapsular métodos. Simplemente cree una estructura de punteros de función e inicialícelos para apuntar a las funciones que desee. Eche un vistazo a lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 para ver un ejemplo.
Robert Martin
Así es. Gracias por el comentario, extendí la respuesta.
sakisk 01 de
Agradable. Una nit más: las funciones en C se pueden sobrecargar (pensar printf), pero al hacerlo pierdes cualquier tipo de comprobación. No hay forma de tener un conjunto finito de declaraciones aceptables: es 1 (y obtienes verificación de tipo) o "muchos" (y pierdes toda verificación de tipo, con un gran riesgo personal). Como con la mayoría de las cosas en C, es posible pero a menudo incómodo.
Robert Martin
¿Los punteros a las funciones son una técnica C avanzada? De Verdad?
Donal Fellows
@DonalFellows Tienes razón, exageré. Eliminado avanzado ... :)
sakisk
0

Soy muy principiante, así que aquí vienen mis 2 bits.

Estoy aprendiendo C y C ++ en Wibit.net con algunos buenos videos básicos, tal vez puedan ayudarlo mucho a tener una visión general de la "situación" (¡no un anuncio!)

Te aconsejo que cambies a C, solo para aprender, ya que eres un aficionado, esto será un placer, no un problema.

Yo aconsejo más. Hazlo en ambos idiomas. Compare la forma y las soluciones que encontrará y utilizará. Estoy seguro de que no será "tan fácil" como esperabas ... ¡pero seguro que aprenderás mucho!

H_7
fuente
1
Muchas gracias, pero no estoy aprendiendo, ya sé C y C ++, estoy preguntando cuál usar para este proyecto específico.
Petruza
¡Uy, mi tiempo para aprender! = P
H_7
1
Además, recomendaría que en lugar de tutoriales en video, obtenga los libros de Kernigan y Stroustrup, un buen IDE (Visual Studio, Eclipse, Xcode) y aprenda codificando los ejemplos, prueba y error y recurriendo a stackoverflow.
Petruza el
-1

Aquí hay pros y contras de C ++ vs. C:

  1. Pasar a C facilitaría permanecer dentro del subconjunto de C ++ elegido, porque el compilador daría un error cuando salga de él. Si el problema principal es permanecer dentro del subconjunto decidido, se debe elegir esta alternativa. (¿Por qué no tenemos soporte de compilación para esto?)
  2. Una vez que pueda permanecer dentro del subconjunto de características de c ++ elegido, lo siguiente es intentar cambiar el subconjunto para deshacerse de las convenciones erróneas que rompen el código. Esto requiere el uso de todo c ++.
  3. Una vez que tenga "permanecer dentro del subconjunto" y "es un buen subconjunto", salga de las funciones de c ++ y comience a pensar en los requisitos.
tp1
fuente