¿Qué puede hacer C ++ que sea demasiado difícil o complicado en cualquier otro idioma?

StackOverflow https://stackoverflow.com/questions/423335

  •  05-07-2019
  •  | 
  •  

Pregunta

Todavía siento que C ++ ofrece algunas cosas que no pueden ser superadas. No es mi intención comenzar una guerra de llamas aquí, por favor, si tienes opiniones fuertes acerca de que no te gusta C ++, no las desactives aquí. Estoy interesado en escuchar a los gurús de C ++ acerca de por qué se apegan a ello.

Estoy particularmente interesado en aspectos de C ++ que son poco conocidos o subutilizados.

Edita: Gente, lee al menos brevemente otras respuestas para asegurarte de que no estás duplicando lo que ya se ha dicho, si estás de acuerdo con lo que alguien más ha dicho, ¡avísalo!

¿Fue útil?

Solución

Me he mantenido con C ++, ya que sigue siendo el lenguaje de propósito general de mayor rendimiento para aplicaciones que necesitan combinar la complejidad y . A modo de ejemplo, escribo software de modelado de superficies en tiempo real para dispositivos portátiles para la industria topográfica. Dados los recursos limitados, Java, C #, etc. simplemente no proporcionan las características de rendimiento necesarias, mientras que los lenguajes de nivel inferior como C son mucho más lentos de desarrollar debido a las características de abstracción más débiles. El rango de niveles de abstracción disponibles para un desarrollador de C ++ es enorme, en un extremo puedo estar sobrecargando operadores aritméticos de manera que puedo decir algo como MaterialVolume = DesignSurface - GroundSurface mientras ejecuto un número de diferentes montones para administrar la memoria de la manera más eficiente para mi aplicación en un dispositivo específico. Combine esto con una gran cantidad de fuentes disponibles de forma gratuita para resolver casi cualquier problema común, y tiene un gran número de poderosos lenguajes de desarrollo.

¿C ++ sigue siendo la solución de desarrollo óptima para la mayoría de los problemas en la mayoría de los dominios? Probablemente no, aunque en un apuro todavía puede usarse para la mayoría de ellos. ¿Sigue siendo la mejor solución para el desarrollo eficiente de aplicaciones de alto rendimiento? En mi humilde opinión sin duda.

Otros consejos

RAII / finalización determinística . No, la recolección de basura no es igual de buena cuando se trata de un recurso compartido escaso.

Acceso sin restricciones a las API del sistema operativo .

Dispararse en el pie.

Ningún otro idioma ofrece una gama tan creativa de herramientas. Punteros, herencia múltiple, plantillas, sobrecarga de operadores y un preprocesador.

Un lenguaje maravillosamente poderoso que también brinda abundantes oportunidades para disparar con el pie.

Edit: Me disculpo si mi escaso intento de humor ha ofendido a algunos. Considero que C ++ es el lenguaje más poderoso que he usado, con capacidades para codificar en el lenguaje ensamblador cuando lo deseo, y en un alto nivel de abstracción cuando lo deseo. C ++ ha sido mi lenguaje principal desde principios de los 90.

Mi respuesta se basó en años de experiencia de dispararme en el pie. Al menos C ++ me permite hacerlo con elegancia.

La destrucción determinista de objetos conduce a algunos patrones de diseño magníficos. Por ejemplo, aunque RAII no es una técnica tan general como la recolección de basura, genera algunas capacidades impresionantes que no se pueden obtener con GC.

C ++ también es único ya que tiene un preprocesador Turing-complete. Esto le permite preferir (como en el opuesto a diferir) muchas tareas de código para compilar el tiempo en lugar del tiempo de ejecución. Por ejemplo, en código real, es posible que tenga una declaración assert () para probar que nunca suceda. La realidad es que tarde o temprano sucederá ... y ocurrirá a las 3:00 am cuando esté de vacaciones. El aserto del preprocesador de C ++ hace la misma prueba en tiempo de compilación. Las afirmaciones en tiempo de compilación fallan entre las 8:00 a. M. Y las 5:00 p. M. Mientras está sentado frente a la computadora mirando la construcción del código; las afirmaciones en tiempo de ejecución fallan a las 3:00 am cuando estás dormido en Hawai'i. Es bastante fácil ver la victoria allí.

En la mayoría de los idiomas, los patrones de estrategia se realizan en tiempo de ejecución y arrojan excepciones en caso de que no coincida el tipo. En C ++, las estrategias se pueden realizar en tiempo de compilación a través de la instalación de preprocesador y se puede garantizar que sea seguro.

Escribir ensamblaje en línea (MMX, SSE, etc.).

Destrucción determinista de objetos. Es decir. Destructores reales. Facilita la gestión de los escasos recursos. Permite RAII.

Acceso más fácil a datos binarios estructurados. Es más fácil convertir una región de memoria como una estructura que analizarla y copiar cada valor en una estructura.

Herencia múltiple. No todo se puede hacer con interfaces. A veces, también desea heredar la funcionalidad real.

Creo que voy a alabar a C ++ por su capacidad de usar plantillas para capturar expresiones y ejecutarlas perezosamente cuando sea necesario. Para aquellos que no saben de qué se trata, aquí es un ejemplo.

Los mixins de plantillas proporcionan una reutilización que no he visto en ningún otro lado. Con ellos puedes construir un objeto grande con mucho comportamiento como si hubieras escrito todo a mano. Pero todos estos pequeños aspectos de su funcionalidad se pueden reutilizar, es especialmente bueno para implementar partes de una interfaz (o todo), donde se implementan varias interfaces. El objeto resultante es rápido como el rayo porque está todo en línea.

La velocidad puede no importar en muchos casos, pero cuando está escribiendo software de componentes, y los usuarios pueden combinar componentes de maneras complicadas para hacer las cosas, la velocidad de la alineación y C ++ parece permitir estructuras mucho más complejas. creado.

Control absoluto sobre el diseño de la memoria, la alineación y el acceso cuando lo necesite. Si eres lo suficientemente cuidadoso, puedes escribir algunos programas que sean muy amigables con el caché. Para programas multiprocesador, también puede eliminar muchas ralentizaciones de los mecanismos de coherencia de caché.

(Bien, puedes hacer esto en C, ensamblaje, y probablemente también en Fortran. Pero C ++ te permite escribir el resto de tu programa en un nivel superior).

Probablemente, esta no sea una respuesta popular, pero creo que lo que distingue a C ++ es su capacidad de compilación, por ejemplo. plantillas y #define. Puede realizar todo tipo de manipulación de texto en su programa usando estas características, muchas de las cuales se han abandonado en idiomas posteriores en nombre de la simplicidad. Para mí eso es mucho más importante que cualquier manipulación de bits de bajo nivel que supuestamente es más fácil o más rápido en C ++.

C #, por ejemplo, no tiene una instalación de macro real. No puede #incluir otro archivo directamente en la fuente, o usar #define para manipular el programa como texto. Piense en cualquier momento que haya tenido que teclear mecánicamente el código repetitivo y sabía que había una mejor manera. Incluso puede haber escrito un programa para generar código para usted. Bueno, el preprocesador de C ++ automatiza todas estas cosas.

Los " genéricos " La facilidad en C # es similarmente limitada en comparación con las plantillas de C ++. C ++ le permite aplicar el operador de punto a un tipo de plantilla T a ciegas, los métodos de llamada (por ejemplo) que pueden no existir y las comprobaciones de corrección solo se aplican una vez que la plantilla se aplica realmente a una clase específica. Cuando eso sucede, si todas las suposiciones que hiciste sobre T realmente se mantienen, entonces tu código se compilará. C # no permite este ... escriba " T " básicamente debe tratarse como un Objeto, es decir, usar solo el mínimo común denominador de operaciones disponibles para todo (asignación, GetHashCode (), Equals ()).

C # ha eliminado el preprocesador y los genéricos reales, en nombre de la simplicidad. Desafortunadamente, cuando uso C #, me encuentro buscando sustitutos para estas construcciones de C ++, que inevitablemente están más hinchadas y en capas que el enfoque de C ++. Por ejemplo, he visto a los programadores trabajar en torno a la ausencia de #incluir de varias maneras: enlazando dinámicamente a ensamblajes externos, redefiniendo constantes en varias ubicaciones (un archivo por proyecto) o seleccionando constantes de una base de datos, etc.

Como dijo la Sra. Crabapple de The Simpson's, esto es "bastante malo, Milhouse".

En términos de Ciencias de la computación, estas características de tiempo de compilación de C ++ permiten el paso de parámetros de llamada por nombre, que se sabe que es más poderoso que la llamada por valor y la llamada por referencia.

Una vez más, quizás esta no sea la respuesta popular, por ejemplo, cualquier texto C ++ introductorio lo advertirá de #define. Pero después de haber trabajado con una gran variedad de idiomas durante muchos años y de haber tenido en cuenta la teoría detrás de todo esto, creo que muchas personas están dando malos consejos. Este parece ser especialmente el caso en el subcampo diluido conocido como " IT. & Quot;

Técnicamente, creo que no hay ninguno, ¡de verdad!

Sinceramente, no creo que C ++ pueda hacer algo que El lenguaje D no pueda. No importa qué habilidad tenga C ++, siempre es más difícil y más desordenado que D o cualquier otro idioma. Incluso una cosa simple como una declaración de clase es mucho más difícil y más complicada en C ++ que en cualquier otro idioma.

Lo único que C ++ puede hacer es ser compatible con millones de líneas de códigos ya escritos en C ++.
Esto es lo único que no puede hacer otro lenguaje que no sea C ++ :)

Pasar estructuras POD a través de procesos con una sobrecarga mínima. En otras palabras, nos permite manejar fácilmente blobs de datos binarios.

C # y Java te obligan a poner tu función 'main ()' en una clase. Lo encuentro raro, porque diluye el significado de una clase.

Para mí, una clase es una categoría de objetos en su dominio de problema. Un programa es no tal objeto. Por lo tanto, nunca debe haber una clase llamada 'Programa' en su programa. Esto sería equivalente a una prueba matemática que usa un símbolo para anotarse a sí mismo (la prueba) junto con símbolos que representan objetos matemáticos. Será simplemente extraño e inconsistente.

Afortunadamente, a diferencia de C # y Java, C ++ permite funciones globales. Eso permite que su función main () exista fuera. Por lo tanto, C ++ ofrece una implementación más simple, más consistente y quizás más verdadera del lenguaje orientado a objetos. Por lo tanto, esto es algo que C ++ puede hacer, pero C # y Java no pueden.

Creo que la sobrecarga del operador es una característica bastante buena. Por supuesto, se puede abusar mucho (como en Boost lambda).

Control estricto sobre los recursos del sistema (especialmente memoria) al tiempo que ofrece potentes mecanismos de abstracción opcionalmente. El único lenguaje que conozco que puede acercarse a C ++ en este sentido es Ada.

C ++ proporciona un control completo sobre la memoria y, como resultado, hace que el flujo de ejecución del programa sea mucho más predecible. No solo puede decir con precisión en qué momento se producen las asignaciones y desasignaciones de memoria, puede definir sus propios montones, tener múltiples montones para diferentes propósitos y decir con precisión a dónde se asignan los datos en la memoria. Esto suele ser útil cuando se programa en sistemas integrados / en tiempo real, como consolas de juegos, teléfonos celulares, reproductores de mp3, etc., que:

  1. tiene límites superiores estrictos en la memoria que son fáciles de alcanzar (se contrae con una PC que se vuelve más lenta a medida que se queda sin memoria física)
  2. frecuentemente tiene un diseño de memoria no homogéneo. Es posible que desee asignar objetos de un tipo en una parte de la memoria física, y objetos de otro tipo en otra parte.
  3. tienen restricciones de programación en tiempo real. Llamar inesperadamente al recolector de basura en el momento equivocado puede ser desastroso.

AFAIK, C y C ++ son la única opción sensata para hacer este tipo de cosas.

Bueno, para ser sincero, puede hacer casi cualquier cosa si está dispuesto a escribir suficiente código.

Entonces, para responder a tu pregunta, no, no hay nada que no puedas hacer en otro idioma que C ++ no pueda hacer. ¿Cuánta paciencia tienes y estás dispuesto a dedicar las largas noches de insomnio para que funcione?

Hay cosas que los envoltorios de C ++ facilitan (porque pueden leer los archivos de encabezado), como el desarrollo de Office. Pero, de nuevo, es porque alguien escribió mucho código para "envolver" para usted en un RCW o "Contenedor invocable en tiempo de ejecución"

EDITAR: También te das cuenta de que esta es una pregunta cargada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top