C++ | |
---|---|
Semántica | multi- paradigma : orientado a objetos , genérico , procedimental , metaprogramación |
clase de idioma | lenguaje de programación orientado a objetos , lenguaje de programación multiparadigma , lenguaje de programación procedimental , lenguaje de programación funcional , lenguaje de programación genérico , lenguaje de programación , lenguaje de forma libre [d] y lenguaje de programación compilado |
tipo de ejecución | compilado |
Apareció en | 1983 |
Autor | Stroustrup, Bjorn |
extensión de archivo | .cc, .cpp, .cxx, .c, .c++, .h, .hpp, .hh, .hxxo.h++ |
Liberar | |
sistema de tipos | estático |
Implementaciones principales | GNU C++ , Microsoft Visual C++ , Intel C++ compilador , Open64 C++ Compiler , Clang , Comeau C/C++ , Embarcadero C++ Builder , Watcom C++ compilador , Digital Mars C++, Oracle Solaris Studio C++ compilador, Turbo C++ |
Dialectos | ISO/CEI 14882 C++ |
sido influenciado | C , Simula , Algol 68 , Clu , ML y Ada |
Sitio web | isocpp.org _ |
Archivos multimedia en Wikimedia Commons |
C ++ (pronunciado c-plus-plus [2] [3] ) es un lenguaje de programación de propósito general compilado , tipificado estáticamente .
Admite paradigmas de programación como la programación procedimental , la programación orientada a objetos y la programación genérica . El lenguaje tiene una rica biblioteca estándar que incluye contenedores y algoritmos comunes , E/S, expresiones regulares, compatibilidad con subprocesos múltiples y más. C++ combina características de lenguajes de alto y bajo nivel [4] [5] . En comparación con su predecesor, el lenguaje C , se presta la mayor atención al soporte para la programación genérica y orientada a objetos [5] .
C++ es ampliamente utilizado para el desarrollo de software, siendo uno de los lenguajes de programación más populares [opiniones 1] [opiniones 2] . Su alcance incluye la creación de sistemas operativos , una variedad de programas de aplicación, controladores de dispositivos , aplicaciones para sistemas integrados, servidores de alto rendimiento y juegos de computadora. Hay muchas implementaciones del lenguaje C++, tanto gratuitas como comerciales, y para varias plataformas. Por ejemplo, en la plataforma x86 , estos son GCC , Visual C++ , Intel C++ Compiler , Embarcadero (Borland) C++ Builder y otros. C++ ha tenido un gran impacto en otros lenguajes de programación, sobre todo en Java y C# .
La sintaxis de C++ se hereda del lenguaje C. Uno de los principios de diseño originales era mantener la compatibilidad con C. Sin embargo, C++ no es estrictamente un superconjunto de C; El conjunto de programas que los compiladores de C y C++ pueden traducir igualmente bien es bastante grande, pero no incluye todos los programas de C posibles .
Etapa histórica de desarrollo [6] | Año |
---|---|
lenguaje BCPL | 1966 |
El lenguaje B (desarrollo original de Thompson bajo UNIX ) | 1969 |
lenguaje C | 1972 |
C con clases | 1980 |
C84 | 1984 |
Frente (Edición E) | 1984 |
frente (versión 1.0) | 1985 |
Herencia múltiple/virtual | 1988 |
Programación genérica ( plantillas ) | 1991 |
ANSI C++ / ISO-C++ | 1996 |
ISO/CEI 14882:1998 | 1998 |
ISO/CEI 14882:2003 | 2003 |
C++/CLI | 2005 |
TR1 | 2005 |
C++11 | 2011 |
C++14 | 2014 |
C++17 | 2017 |
C++20 | 2020 |
El lenguaje se originó a principios de la década de 1980 , cuando el empleado de Bell Labs , Björn Stroustrup , ideó una serie de mejoras en el lenguaje C para sus propias necesidades [7] . Cuando Stroustrup comenzó a trabajar en Bell Labs a fines de la década de 1970 en problemas de la teoría de colas (aplicada al modelado de llamadas telefónicas), descubrió que los intentos de utilizar los lenguajes de modelado existentes en ese momento eran ineficaces y el uso de lenguajes de máquina altamente eficientes. fue demasiado difícil debido a su limitada expresividad. Por ejemplo, el lenguaje Simula tiene características que serían muy útiles para desarrollar software de gran tamaño, pero es demasiado lento, y el lenguaje BCPL es lo suficientemente rápido, pero demasiado parecido a los lenguajes de bajo nivel, y no es adecuado para desarrollar software de gran tamaño.
Recordando la experiencia de su disertación, Stroustrup decidió complementar el lenguaje C (el sucesor de BCPL) con las capacidades disponibles en el lenguaje Simula. El lenguaje C, siendo el lenguaje base del sistema UNIX en el que se ejecutaban las computadoras Bell, es rápido, rico en funciones y portátil. Stroustrup le agregó la capacidad de trabajar con clases y objetos. Como resultado, los problemas prácticos de modelado resultaron ser accesibles tanto en términos de tiempo de desarrollo (debido al uso de clases similares a Simula) como en términos de tiempo de cálculo (debido a la velocidad de C). Las primeras adiciones a C fueron clases (con encapsulación ), herencia de clases, verificación estricta de tipos, funciones en línea y argumentos predeterminados . Las primeras versiones del lenguaje, originalmente llamado "C con clases", han estado disponibles desde la década de 1980 .
Mientras desarrollaba C con clases , Stroustrup escribió el programa cfront , un compilador que transforma el código fuente de C con clases en código fuente simple de C. Esto nos permitió trabajar en un nuevo lenguaje y usarlo en la práctica, usando la infraestructura ya disponible en UNIX para desarrollo en C. Un nuevo idioma, inesperadamente para el autor, ganó gran popularidad entre sus colegas y pronto Stroustrup ya no pudo apoyarlo personalmente, respondiendo miles de preguntas.
Para 1983, se agregaron nuevas funciones al lenguaje, como funciones virtuales, sobrecarga de funciones y operadores, referencias, constantes, control del usuario sobre la administración de memoria libre, verificación de tipos mejorada y un nuevo estilo de comentario ( //). El lenguaje resultante ya no es solo una versión aumentada del C clásico y ha sido renombrado de C con clases a "C++". Su primer lanzamiento comercial tuvo lugar en octubre de 1985 .
Antes del inicio de la estandarización oficial, el lenguaje fue desarrollado principalmente por Stroustrup en respuesta a las solicitudes de la comunidad de programación. La función de las descripciones del lenguaje estándar fue realizada por los trabajos impresos de Stroustrup en C ++ (una descripción del lenguaje, un manual de referencia, etc.). Recién en 1998 se ratificó el estándar internacional para el lenguaje C++: ISO/IEC 14882:1998 "Estándar para el lenguaje de programación C++"; después de la adopción de correcciones técnicas a la norma en 2003, la siguiente versión de esta norma es ISO/IEC 14882:2003 [8] .
En 1985, salió la primera edición de The C++ Programming Language , brindando la primera descripción del lenguaje, lo cual fue sumamente importante debido a la falta de un estándar oficial. En 1989, se lanzó la versión 2.0 de C++. Sus nuevas características incluían herencia múltiple, clases abstractas, funciones de miembros estáticos, funciones constantes y miembros protegidos. En 1990, se publicó la "Guía de referencia comentada de C++", que luego se convirtió en la base del estándar. Las actualizaciones recientes han incluido plantillas, excepciones, espacios de nombres, nuevas conversiones y el tipo booleano. La biblioteca de plantillas estándar (STL) desarrollada por Alexander Stepanov y Meng Li fue elegida como base para almacenar y acceder a algoritmos genéricos .
La biblioteca estándar de C++ también ha evolucionado junto con ella. La primera adición a la biblioteca estándar de C++ fueron los flujos de E/S, que proporcionan un medio para reemplazar los C printfy scanf. Posteriormente, el desarrollo más significativo de la biblioteca estándar fue la inclusión de la Biblioteca de plantillas estándar .
C++ continúa evolucionando para cumplir con los requisitos modernos. Uno de los grupos que desarrolla el lenguaje C++ y envía propuestas para mejorarlo al comité de estandarización de C++ es Boost , que se dedica, entre otras cosas, a mejorar las capacidades del lenguaje añadiéndole características de metaprogramación .
Nadie posee los derechos del lenguaje C++, es gratuito. Sin embargo, el documento estándar de idioma en sí mismo (a excepción de los borradores) no está disponible gratuitamente [10] . Como parte del proceso de estandarización, ISO produce varios tipos de publicaciones. En particular, los informes técnicos y las especificaciones técnicas se publican cuando "el futuro está a la vista, pero no existe una posibilidad inmediata de acuerdo para la publicación de una norma internacional". Hasta 2011, se publicaron tres informes técnicos sobre C++: TR 19768: 2007 (también conocido como C++ Technical Report 1) para extensiones de biblioteca principalmente integradas en C++ 11, TR 29124: 2010 para funciones matemáticas especiales y TR 24733: 2011 para Aritmética de punto flotante decimal. Especificación técnica DTS 18822:. 2014 (por sistema de archivos) fue aprobado a principios de 2015, y el resto de las especificaciones están en desarrollo y en espera de aprobación [11] .
En marzo de 2016 se creó en Rusia el grupo de trabajo WG21 C++ . El grupo se organizó para recopilar propuestas para el estándar C++, presentarlas al comité y defenderlas en las reuniones generales de la Organización Internacional de Normalización (ISO) [12] .
El nombre de idioma resultante proviene del operador de incremento de posfijo C unario ++(incrementa el valor de una variable en uno). No se usó el nombre C+ porque es un error de sintaxis en C y, además, el nombre fue tomado por otro idioma. El lenguaje tampoco se llamó D porque " es una extensión de C y no intenta solucionar problemas eliminando elementos de C " [7] .
En El diseño y la evolución de C++ [13] , Bjorn Stroustrup describe los principios que siguió al diseñar C++. Estos principios explican por qué C++ es como es. Algunos:
El estándar C++ consta de dos partes principales: una descripción del lenguaje principal y una descripción de la biblioteca estándar.
Al principio, el lenguaje se desarrolló fuera del marco formal, de manera espontánea, de acuerdo con las tareas a las que se enfrentaba. El desarrollo del lenguaje fue acompañado por el desarrollo del compilador cruzado cfront . Las innovaciones en el lenguaje se reflejaron en el cambio en el número de versión del compilador cruzado. Estos números de versión de compilador cruzado se extendieron al lenguaje en sí, pero las versiones de C ++ no se están discutiendo actualmente. No fue hasta 1998 que el idioma se estandarizó.
Un espacio de nombres sin nombre es un caso especial. Todos los nombres descritos en él están disponibles solo en la unidad de traducción actual y tienen vinculación local. El espacio de nombres stdcontiene las bibliotecas estándar de C++.
Los siguientes tipos integrados están disponibles en C++. Los tipos de C++ son casi idénticos a los tipos de datos de C :
Los operadores de comparación devuelven el tipo bool. Las expresiones entre paréntesis después ifde , while se convierten al tipo bool[14] .
El lenguaje introdujo el concepto de referencias, y del estándar C++11 , rvalues - referencias y referencias de reenvío . (ver enlace (C++) )
C++ agrega características orientadas a objetos a C. Introduce clases que proporcionan las tres propiedades más importantes de OOP : encapsulación , herencia y polimorfismo .
En el estándar de C++, una clase es un tipo definido por el usuario declarado mediante una de las palabras clave o class, structuna unionestructura es una clase definida por struct, y una unión es una clase definida por union. Dependiendo de la palabra clave utilizada, algunas propiedades de la propia clase también cambian. Por ejemplo, en una clase declarada con struct, los miembros sin un modificador de acceso asignado manualmente serán públicos en lugar de privados de forma predeterminada.
En el cuerpo de una definición de clase, puede especificar tanto las declaraciones de función como su definición. En este último caso, la función es inline ( inline). Las funciones miembro no estáticas pueden tener consty calificadores volatile, así como un calificador de referencia ( &o &&).
C++ admite la herencia múltiple . Las clases base (clases antepasadas) se especifican en el encabezado de la declaración de clase, posiblemente con especificadores de acceso. La herencia de cada clase puede ser pública, protegida o privada:
Modo de acceso/herencia de miembro de clase base | miembro privado | miembro protegido | miembro público |
---|---|---|---|
herencia privada | no disponible | privado | privado |
herencia protegida | no disponible | protegido | protegido |
herencia pública | no disponible | protegido | público |
De forma predeterminada, la clase base se hereda como privada.
Como resultado de la herencia, la clase hija recibe todos los campos de las clases antecesoras y todos sus métodos; podemos decir que cada instancia de la clase descendiente contiene una sub- instancia de cada una de las clases antepasadas. Si una clase de antepasado se hereda varias veces (esto es posible si es el antepasado de varias clases base de la clase que se está creando), las instancias de la clase descendiente incluirán tantas subinstancias de esta clase de antepasado. Para evitar este efecto si no se desea, C++ soporta el concepto de herencia virtual . Al heredar, la clase base puede declararse virtual; para todas las instancias virtuales de la clase antecesora en el árbol de herencia de la clase descendiente, solo se crea una subinstancia en la descendiente.
C++ admite polimorfismo dinámico y polimorfismo paramétrico .
El polimorfismo paramétrico está representado por:
El polimorfismo dinámico se implementa mediante métodos virtuales y una jerarquía de herencia. En C++, un tipo es polimórfico si tiene al menos un método virtual. Ejemplo de jerarquía:
figura de clase { público : sorteo de vacío virtual () = 0 ; // método virtual puro virtual ~ Figura (); // si hay al menos un método virtual, el destructor debe hacerse virtual }; plaza de clase : figura pública { público : void Dibujar () anular ; }; círculo de clase : figura pública { público : void Dibujar () anular ; };Aquí la clase Figure es abstracta (e incluso clase de interfaz ), ya que el método Draw no está definido. No se pueden crear objetos de esta clase, pero se pueden utilizar referencias o punteros de tipo Figura. La elección de la implementación del método Draw se realizará en tiempo de ejecución en función del tipo real del objeto.
La encapsulación en C++ se implementa especificando el nivel de acceso a los miembros de la clase: son públicos (public, public), protected ( protected) y private (private, private). En C++, las estructuras difieren formalmente de las clases solo en que, por defecto, el nivel de acceso a los miembros de la clase y el tipo de herencia para una estructura son públicos, mientras que para una clase son privados.
Acceso | privado | protegido | público |
---|---|---|---|
La clase en sí | Sí | Sí | Sí |
Amigos | Sí | Sí | Sí |
herederos | No | Sí | Sí |
Desde afuera | No | No | Sí |
La comprobación de acceso se produce en el momento de la compilación; intentar acceder a un miembro de clase inaccesible provocará un error de compilación.
AmigosLas funciones amigas son funciones que no son funciones miembro y, sin embargo, tienen acceso a miembros protegidos y privados de la clase. Deben declararse en el cuerpo de la clase como friend. Por ejemplo:
matriz de clase { amigo Matrix Multiply ( Matriz m1 , Matriz m2 ); };Aquí, la función Multiplypuede acceder a cualquier campo y función miembro del Matrix.
Tanto la clase entera como una función miembro de la clase pueden ser declaradas amigas. Cuatro restricciones importantes en las relaciones de amistad en C++ son:
En general, esta regla se puede formular de la siguiente manera: "La relación de amistad existe solo entre aquellas clases (clase y función) para las que se declara explícitamente en el código, y actúa solo en la dirección en que se declara".
Una clase predeterminada puede tener seis funciones especiales: constructor predeterminado, constructor de copia, constructor de movimiento, destructor, operador de asignación de copia, operador de asignación de movimiento. También es posible definirlos todos explícitamente (ver la Regla de Tres ).
matriz de clase { público : Matriz ( ) = predeterminado // el compilador creará un constructor predeterminado de Array ( size_t _len ) : largo ( _largo ) { val = nuevo doble [ _len ]; } Array ( const Array & a ) = eliminar ; // copiar constructor eliminado explícitamente Array ( Array && a ); // mueve el constructor ~ Array () { eliminar [] valor ; } Array & operador = ( const Array & rhs ); // copiar operador de asignación Array & operator = ( Array && rhs ); // mueve el operador de asignación double & operator []( size_t i ) { valor de retorno [ i ]; } const double & operador []( size_t i ) const { valor de retorno [ i ]; } protegido : std :: size_t len = 0 ; // inicialización de campo double * val { nullptr }; };Se llama al constructor para inicializar el objeto (del tipo apropiado) cuando se crea, y se llama al destructor para destruir el objeto. Una clase puede tener varios constructores, pero un destructor solo puede tener uno. Los constructores en C++ no se pueden declarar virtuales, pero los destructores pueden declararse para todos los tipos polimórficos, y generalmente se declaran para todos los tipos polimórficos, para garantizar que un objeto referenciado o accesible por puntero se destruya correctamente, sin importar de qué tipo sea la referencia o el puntero. Si al menos una de las clases base tiene un destructor virtual, el destructor de la clase secundaria se vuelve virtual automáticamente.
Las plantillas le permiten generar funciones y clases que se parametrizan con un tipo o valor específico. Por ejemplo, la clase anterior podría implementar una matriz para cualquier tipo de datos:
plantilla < typenameT > _ matriz de clase { ... T & operador []( tamaño_t i ) { valor de retorno [ i ]; } protegido : std :: size_t len { 0 }; // inicialización de campo T * val { nullptr }; };La biblioteca estándar de C++ incluye un conjunto de herramientas que deberían estar disponibles para cualquier implementación del lenguaje para proporcionar a los programadores un uso cómodo de las funciones del lenguaje y proporcionar una base para desarrollar una amplia gama de aplicaciones y bibliotecas especializadas. La biblioteca estándar de C++ incluye una parte de la biblioteca estándar de C. El estándar de C++ contiene una referencia normativa al estándar de C de 1990 y no define de forma independiente las funciones de biblioteca estándar que se toman prestadas de la biblioteca estándar de C.
#includeEl acceso a las capacidades de la biblioteca estándar de C++ se proporciona al incluir los archivos de encabezado estándar apropiados en el programa (a través de la directiva ). En total, 79 de estos archivos están definidos en el estándar C++11. Las instalaciones de la biblioteca estándar se declaran como parte del espacio de nombres estándar. Los archivos de encabezado cuyos nombres coinciden con el patrón "cX", donde X es el nombre del archivo de encabezado de la Biblioteca estándar de C sin extensión (cstdlib, cstring, cstdio, etc.), contienen declaraciones correspondientes a esa parte de la Biblioteca estándar de C. El C Las funciones de biblioteca estándar también se encuentran en el espacio de nombres estándar.
La biblioteca estándar incluye las siguientes secciones:
Los contenedores, cadenas, algoritmos, iteradores y utilidades básicas, con la excepción de los préstamos de la biblioteca C, se denominan colectivamente STL (Standard Template Library - biblioteca de plantillas estándar). Inicialmente, esta biblioteca era un producto separado y su abreviatura se descifraba de manera diferente, pero luego ingresó a la biblioteca estándar de C ++ como un elemento integral. El nombre refleja el hecho de que los mecanismos de programación generalizados (plantillas de C++ - plantilla) se utilizan para implementar herramientas de propósito general (contenedores, cadenas, algoritmos). Los escritos de Stroustrup detallan las razones por las que se hizo esta elección. Los principales son la mayor universalidad de la solución elegida (los contenedores de plantillas, a diferencia de los contenedores de objetos, se pueden usar fácilmente para tipos que no son objetos y no requieren un ancestro común para los tipos de elementos) y su eficiencia técnica (por regla general, los contenedores de plantillas las operaciones no requieren llamadas a funciones virtuales y se pueden incrustar fácilmente (en línea), lo que en última instancia proporciona una mejora en el rendimiento).
Comenzando con el estándar C++ 11, se han agregado las siguientes características:
El STL, antes de ser incluido en el estándar C++, fue un desarrollo de terceros, primero de HP y luego de SGI . El lenguaje estándar no lo llama "STL" ya que esta biblioteca se ha convertido en una parte integral del lenguaje; sin embargo, muchas personas todavía usan este nombre para distinguirlo del resto de la biblioteca estándar (Flujos de E/S ( iostream ), subsección C y otros).
Un proyecto llamado STLport [15] basado en SGI STL mantiene actualizadas las clases STL, IOstream y string. Varios otros proyectos también están desarrollando usos privados de la biblioteca estándar.
La elección de C como base para crear un nuevo lenguaje de programación se explica por el hecho de que el lenguaje C:
A pesar de una serie de deficiencias bien conocidas del lenguaje C, Stroustrup eligió usarlo como base porque "C tiene sus problemas, pero un lenguaje diseñado desde cero los tendría, y conocemos los problemas de C". Además, esto nos permitió obtener rápidamente un prototipo de compilador ( cfront ) que solo traducía los elementos de sintaxis agregados al lenguaje C original.
A medida que se desarrollaba C++, se incluyeron otras características que anulan las capacidades de las construcciones de C, y se planteó repetidamente la cuestión de abandonar la compatibilidad del lenguaje mediante la eliminación de construcciones en desuso. Sin embargo, la compatibilidad se ha mantenido por las siguientes razones:
Las nuevas funciones de C++ incluyen declaraciones de expresiones, conversiones de tipos de funciones, operadores newy delete, tipo bool, referencias, constancia extendida, funciones en línea, argumentos predeterminados, anulaciones, espacios de nombres, clases (incluidas todas las funciones relacionadas con clases, como herencia, funciones miembro, funciones virtuales, funciones abstractas). clases y constructores ), anulaciones de operadores, plantillas, operadores ::, manejo de excepciones, identificación dinámica y más. El lenguaje C++ también es, en muchos casos, más estricto con respecto a la verificación de tipos que C.
C++ introdujo comentarios de doble barra ( //) que estaban en el predecesor de C, BCPL .
constAlgunas funciones de C++ se trasladaron posteriormente a C, como las palabras clave y , las inlinedeclaraciones de bucle fory los comentarios al estilo de C++ ( //). Las implementaciones posteriores de C también introdujeron características que no se encuentran en C++, como macros va_argy manejo mejorado de parámetros de matriz.
Si bien la mayoría del código C también será válido para C++, C++ no es un superconjunto de C y no lo incluye. También hay algún código que es cierto para C pero no para C++. Esto lo distingue de Objective C , otra mejora de C para programación orientada a objetos , que es solo un superconjunto de C.
Hay otras diferencias también. Por ejemplo, C++ no permite llamar a una función main()dentro de un programa, mientras que en C es legal. Además, C++ es más estricto en algunos aspectos; por ejemplo, no permite la conversión implícita entre tipos de punteros no relacionados y no permite funciones que aún no se hayan declarado.
Además, el código que es válido para ambos idiomas puede producir resultados diferentes según el compilador del idioma al que se traduzca. Por ejemplo, en la mayoría de las plataformas, el siguiente programa imprime "C" si lo compila un compilador de C y "C++" si lo compila un compilador de C++. Esto se debe a que las constantes de caracteres en C (por ejemplo, 'a') son de tipo int, pero en C++ son de tipo chary los tamaños de estos tipos suelen diferir.
#incluir <stdio.h> int principal () { printf ( "%s \n " , ( tamaño de ( 'a' ) == tamaño de ( char )) ? "C++" : "C" ); devolver 0 ; }Como señala Stroustrup, "cuanto mejor conozca C, más difícil le resultará evitar programar en C++ al estilo de C, mientras pierde los beneficios potenciales de C++". Con ese fin, hace el siguiente conjunto de recomendaciones para que los programadores de C aprovechen al máximo C++:
El estándar de idioma ISO/IEC 14882:2017 actual se publicó en diciembre de 2017 . Se le conoce extraoficialmente como C++17 . La próxima versión del estándar, prevista para 2020, tiene la designación no oficial C++20 .
Según el autor del lenguaje, Björn Stroustrup [19] [20] [21] , al hablar sobre el desarrollo posterior y las perspectivas del lenguaje, se puede distinguir lo siguiente:
Este es un programa de ejemplo ¡Hola, mundo! , que imprime un mensaje en la consola utilizando la biblioteca estándar y sale.
#incluir <iostream> utilizando el espacio de nombres estándar ; int principal () { cout << "¡Hola, mundo!" << endl ; devolver 0 ; }El C++ moderno le permite resolver problemas más complejos de forma sencilla. Este ejemplo demuestra, entre otras cosas, el uso de los contenedores de la biblioteca de plantillas estándar ( STL ).
#include <iostream> // para usar std::cout #include <vector> // contiene una matriz dinámica #include <mapa> // contiene el tipo de datos del diccionario #incluir <cadena> int principal () { // Importar todas las declaraciones del espacio de nombres "std" al espacio de nombres global. utilizando el espacio de nombres estándar ; // Declaramos un contenedor asociativo con claves de cadena y datos como vectores de cadena. mapa < cadena , vector < cadena > > elementos ; // Agrega un par de personas a este contenedor asociativo y dales algunos artículos. elementos [ "Anya" ]. push_back ( "bufanda" ); elementos [ "Dmitry" ]. push_back ( "boletos" ); elementos [ "Anya" ]. push_back ( "cachorro" ); // Recorrer todos los objetos en el contenedor for ( const auto & person : items ) { // persona es un par de dos objetos: persona.primero es su nombre, // persona.segundo es una lista de sus elementos (vector de cadenas) cout << persona . primero << " lleva " << persona . segundo _ tamaño () << "elementos" << endl ; } }Este ejemplo importa todos los nombres del espacio de nombres estándar para simplificar. En un programa real, esto no se recomienda, ya que puede encontrar colisiones de nombres. El idioma le permite importar objetos individuales:
#incluir <vector> int principal () { usando std :: vector ; vector < int > mi_vector ; }En C++ (como en C), si la ejecución del programa llega al final de la función main(), esto es equivalente a return 0;. Esto no es cierto para ninguna otra función que no sea main().
Se conocen varios estudios en los que se ha intentado comparar de forma más o menos objetiva varios lenguajes de programación, uno de los cuales es C++. En particular:
El lenguaje Ada está cerca de C++ en términos de su conjunto de características y áreas de aplicación: es un lenguaje estructural compilado con una adición orientada a objetos similar a Simula (el mismo modelo de "Algol con clases" que en C++), escritura estática , herramientas de programación genéricas, diseñadas para el desarrollo de sistemas de software grandes y complejos. Al mismo tiempo, es fundamentalmente diferente en ideología: a diferencia de C ++, Ada se construyó sobre la base de condiciones cuidadosamente elaboradas previamente de fabricantes de software complejos con mayores requisitos de confiabilidad, lo que dejó una huella en la sintaxis y la semántica del idioma.
Hay pocas comparaciones directas de la eficiencia de codificación de Ada y C++. En el artículo [22] mencionado anteriormente, la solución del problema del modelo en Ada resultó en un código aproximadamente un 30% más pequeño en tamaño (en líneas) que en C++. La comparación de las propiedades de los propios idiomas se encuentra en muchas fuentes, por ejemplo, el artículo de Jim Rogers sobre AdaHome [28] enumera más de 50 puntos de diferencias en las propiedades de estos idiomas, la mayoría de los cuales están a favor de Ada. (más funciones, comportamiento más flexible, menos posibilidades de errores). Aunque muchas de las declaraciones de los seguidores de Ada son controvertidas, y algunas de ellas están claramente desactualizadas, en general se puede concluir:
En un artículo de Stephen Zeiger de Rational Software Corporation [29] , se afirma que el desarrollo en Ada es generalmente un 60% más barato y da como resultado un código con 9 veces menos defectos que en C. Aunque estos resultados no se pueden transferir directamente a C++, siguen siendo interesantes dado que muchas de las deficiencias de C++ se heredan de C.
Java no puede considerarse un reemplazo completo de C++, está diseñado como un lenguaje seguro con un umbral de entrada bajo para desarrollar aplicaciones personalizadas con alta portabilidad [30] y es fundamentalmente inadecuado para algunos tipos de aplicaciones que se desarrollan en C++. Sin embargo, dentro de su alcance, Java es un competidor muy real de C++. Los beneficios de Java se citan comúnmente como:
Al mismo tiempo, el uso del recolector de basura y la máquina virtual crean limitaciones que son difíciles de superar. Los programas Java tienden a ser más lentos, requieren mucha más memoria y la máquina virtual aísla el programa del sistema operativo, lo que hace imposible la programación de bajo nivel.
Un estudio empírico [24] no encontró diferencias significativas en la velocidad de desarrollo en C++ y Java. El estudio [26] también mostró que la idea de una diferencia significativa en la velocidad de los programas en estos lenguajes no siempre es correcta: en dos de cada tres pruebas, la velocidad de las aplicaciones en Java y C++ resultó ser comparable. Al mismo tiempo, Java es más conciso: la diferencia en la cantidad de código fue de un 10-15 %.
El C original continúa evolucionando, se están desarrollando muchos proyectos a gran escala en él: es el lenguaje principal para desarrollar sistemas operativos, los motores de juego de muchos juegos dinámicos y una gran cantidad de aplicaciones de aplicación están escritas en él. Varios expertos argumentan que reemplazar C con C ++ no aumenta la eficiencia del desarrollo, sino que genera una complicación innecesaria del proyecto, reduce la confiabilidad y aumenta los costos de mantenimiento. En particular:
No hay evidencia convincente de que C++ sea superior a C en términos de productividad del programador o propiedades del programa. Aunque hay estudios [32] que indican que los programadores de C dedican alrededor del 30-40 % del tiempo total de desarrollo (excluyendo la depuración) a la gestión de la memoria, cuando se compara la productividad general de los desarrolladores [22] , C y C++ están cerca.
En la programación de bajo nivel, muchas de las nuevas funciones de C++ se vuelven inaplicables debido al aumento de la sobrecarga: las funciones virtuales requieren un cálculo dinámico de direcciones reales (RVA), las plantillas conducen a una sobrecarga de código y capacidades de optimización deficientes, la biblioteca en tiempo de ejecución (RTL) es muy grande, y su rechazo priva a la mayoría de las funciones de C ++ (aunque solo sea por la falta de disponibilidad de las operaciones new/ delete). Como resultado, el programador deberá limitarse a la funcionalidad heredada de C, lo que hace que no tenga sentido usar C ++:
… la única forma de tener un C++ portátil bueno, eficiente y de bajo nivel es limitarse a todas las cosas que están trivialmente disponibles en C. Y limitar el proyecto a C significará que la gente no lo tirará, y que habrá muchos programadores disponibles que realmente entiendan bien las funciones de bajo nivel y no las abandonen debido al idiota "modelo de objetos". disparates.
… cuando la eficiencia es primordial, las "ventajas" de C++ serán un gran error.
En un experimento [22] , los lenguajes funcionales y de secuencias de comandos, en particular Haskell , mostraron una ganancia de 2 o 3 veces en el tiempo de programación y el tamaño del código en comparación con los programas C++. Por otro lado, los programas en C++ resultaron ser mucho más rápidos. Los autores reconocen que sus datos no constituyen una muestra representativa y se abstienen de sacar conclusiones categóricas.
En otro experimento [34] , los lenguajes funcionales estrictos ( Standard ML , OCaml ) mostraron una aceleración general del desarrollo por un factor de 10 (principalmente debido a la detección temprana de errores) con indicadores de rendimiento aproximadamente iguales (muchos compiladores en varios modos fueron usó).
En un estudio de Lutz Prehelt [24] , basado en los resultados del procesamiento de unas 80 soluciones escritas por voluntarios, se obtuvieron las siguientes conclusiones, en particular:
La mayoría de las veces, los críticos no oponen C++ a ningún otro lenguaje específico, pero argumentan que el rechazo de usar un solo lenguaje que tiene numerosos defectos a favor de descomponer un proyecto en subtareas que pueden resolverse en varios lenguajes que son más adecuados para ellos hace que el desarrollo consuma significativamente menos tiempo, al tiempo que mejora los indicadores de calidad de la programación [35] [36] . Por la misma razón, se critica mantener la compatibilidad con C: si una parte de la tarea requiere características de bajo nivel, es más razonable separar esta parte en un subsistema separado y escribirlo en C.
A su vez, los partidarios de C ++ afirman que la eliminación de los problemas técnicos y organizativos de la interacción entre lenguas mediante el uso de un lenguaje universal en lugar de varios especializados es más importante que las pérdidas por la imperfección de este lenguaje universal, es decir, el la gran amplitud del conjunto de funciones de C ++ es una excusa para las deficiencias de cada función individual; incluso las desventajas heredadas de C se justifican por las ventajas de la compatibilidad (ver arriba ).
Por lo tanto, las mismas propiedades de C ++ (volumen, complejidad, eclecticismo y falta de un nicho de aplicación objetivo específico) son consideradas por los partidarios como "la principal ventaja ", y por los críticos, como " la principal desventaja ".
La ideología del lenguaje confunde el " control de comportamiento " con el " control de eficiencia ": el principio " no pagas por lo que no usas " sugiere que proporcionar al programador un control completo sobre todos los aspectos de la ejecución del programa en un nivel bastante bajo es una condición necesaria y suficiente para lograr una alta eficiencia del código. De hecho, esto no es cierto para ningún programa grande: imponer una optimización de bajo nivel en el programador, que un compilador de lenguaje específico de dominio de alta calidad obviamente puede realizar de manera más eficiente, solo conduce a un aumento en la cantidad de código, un aumento en la intensidad del trabajo de programación y una disminución en la comprensión y capacidad de prueba del código. Así, el principio de “no pagar por lo que no se usa” realmente no proporciona los beneficios deseados en eficiencia, sino que afecta negativamente a la calidad.
Programación orientada a objetos y componentesSegún Alan Kay , el modelo de objeto " Algol con clases" utilizado en C++ es inferior al modelo "todo es un objeto" [37] utilizado en Objective-C en términos de alcance general, reutilización de código , comprensibilidad, modificabilidad y comprobabilidad. .
El modelo de herencia de C++ es complejo, difícil de implementar y, al mismo tiempo, provoca la creación de jerarquías complejas con relaciones no naturales entre clases (por ejemplo, herencia en lugar de anidamiento). El resultado es la creación de clases estrechamente acopladas con funciones vagamente separadas. Por ejemplo, en [38] se da un ejemplo educativo y de recomendación de la implementación de la clase "lista" como una subclase de la clase "elemento de lista" que, a su vez, contiene funciones de acceso para otros elementos de lista. Esta relación de tipos es matemáticamente absurda e irreproducible en lenguajes más rigurosos. La ideología de algunas bibliotecas requiere la conversión manual de tipos hacia arriba y hacia abajo en la jerarquía de clases ( static_casty dynamic_cast), lo que viola la seguridad de tipos del lenguaje. La alta viscosidad de las soluciones de C++ puede requerir que se vuelvan a desarrollar grandes porciones del proyecto con cambios mínimos más adelante en el proceso de desarrollo. Un vívido ejemplo de tales problemas se puede encontrar en [35]
Como señala Ian Joyner [39] , C++ erróneamente equipara la encapsulación (es decir, colocar datos dentro de objetos y separar la implementación de la interfaz) y la ocultación de la implementación. Esto complica el acceso a los datos de la clase y requiere que su interfaz se implemente casi exclusivamente a través de funciones de acceso (lo que, a su vez, aumenta la cantidad de código y lo complica).
La coincidencia de tipos en C++ se define a nivel de identificadores, no de firmas. Esto hace que sea imposible reemplazar los componentes basados en la coincidencia de la interfaz, por lo que la inclusión de una nueva funcionalidad implementada a nivel de biblioteca en el sistema requiere la modificación manual del código existente [40] . Como señala Linus Torvalds [33] , en C++, "el código parece abstracto solo mientras no sea necesario cambiarlo".
La crítica de C++ desde el punto de vista de OOP se da en [39] .
MetaprogramaciónLa metaprogramación generativa de C++ está basada en plantillas y preprocesadores , requiere mucha mano de obra y tiene un alcance limitado. El sistema de plantillas de C++ es en realidad una variante en tiempo de compilación del lenguaje de programación funcional primitivo. Este lenguaje casi no se superpone con el propio C ++, por lo que el potencial de crecimiento en la complejidad de las abstracciones es limitado. Los programas que utilizan plantillas de C++ tienen una comprensión y una capacidad de prueba extremadamente bajas, y el propio desenvolvimiento de la plantilla genera un código ineficiente, ya que el lenguaje de la plantilla no proporciona ningún medio para la optimización (consulte también la sección #Eficiencia informática ). Los lenguajes específicos de dominio integrados implementados de esta manera aún requieren el conocimiento de C ++ en sí mismo, lo que no proporciona una división del trabajo completa. Por lo tanto, la capacidad de C++ para ampliar las capacidades de C++ en sí es bastante limitada [41] [42] .
MultiplataformaEscribir código C++ portátil requiere mucha habilidad y experiencia, y es muy probable que el código C++ "descuidado" no sea portátil [43] . Según Linus Torvalds , para lograr una portabilidad de C++ similar a la de C, el programador debe limitarse a las características de C++ heredadas de C [33] . El estándar contiene muchos elementos definidos como "definidos por la implementación" (por ejemplo, el tamaño de los punteros a métodos de clase en diferentes compiladores varía de 4 a 20 bytes [44] ), lo que empeora la portabilidad de los programas que los utilizan.
La naturaleza directiva de la estandarización del lenguaje , la retrocompatibilidad incompleta y la inconsistencia de los requisitos de las diferentes versiones del estándar generan problemas en la transferencia de programas entre diferentes compiladores e incluso versiones de los mismos compiladores.
El lenguaje contiene herramientas que permiten al programador violar la disciplina de programación dada en un caso particular. Por ejemplo, un modificador constestablece la propiedad de inmutabilidad de estado para un objeto, pero el modificador mutableestá diseñado específicamente para forzar el permiso para cambiar el estado dentro de un objeto const, es decir, violar la restricción de constness. Además, se permite eliminar dinámicamente un atributo constde un objeto constante, convirtiéndolo en un valor L. La presencia de tales características en el lenguaje hace que los intentos de verificar formalmente el código no tengan sentido y el uso de restricciones para la optimización es imposible.
Sustitución de macros no controladaLas facilidades de sustitución de macro C ( #define) son tan poderosas como peligrosas. Se conservan en C++ a pesar de que, para todas las tareas para las que se proporcionaron en C, C++ proporcionaba recursos más estrictos y especializados: plantillas, sobrecarga de funciones, funciones en línea, espacios de nombres, escritura más avanzada, extensión de la aplicación, el modificador const. , etc. Hay muchas macros potencialmente peligrosas en las bibliotecas estándar heredadas de C [45] . La metaprogramación de plantillas también se combina a veces con el uso de sustitución de macros para proporcionar los llamados. " azúcar sintáctico ".
Problemas de sobrecargaLos principios de C++ de función y sobrecarga de operadores conducen a una duplicación de código significativa. Originalmente destinado a introducir el llamado " azúcar sintáctico ", la sobrecarga de operadores en C++ fomenta el comportamiento descontrolado de los operadores elementales para diferentes tipos. Esto aumenta drásticamente el riesgo de errores, sobre todo porque es imposible introducir una nueva sintaxis y cambiar la existente (por ejemplo, crear nuevos operadores o cambiar las prioridades o la asociatividad), aunque la sintaxis de los operadores estándar de C ++ es adecuada a la semántica de todo tipo que puede ser necesario introducir en el programa. Algunos problemas son creados por la posibilidad de una fácil sobrecarga de los operadores / , lo que puede generar errores extremadamente insidiosos y difíciles de encontrar. Al mismo tiempo, algunas operaciones intuitivamente esperadas (limpieza de objetos dinámicos en caso de lanzar excepciones) no se realizan en C++, y una parte significativa de funciones y operadores sobrecargados se llaman implícitamente (conversión de tipos, creación de instancias temporales de clases, etc. .). Como resultado, las herramientas originalmente destinadas a hacer que los programas sean más claros y mejorar el desarrollo y la capacidad de mantenimiento se convierten en otra fuente de código innecesariamente complicado y poco confiable. newdelete
El uso de plantillas de C++ es polimorfismo paramétrico a nivel de código fuente, pero cuando se traduce, se convierte en polimorfismo ad hoc (es decir, sobrecarga de funciones), lo que conduce a un aumento significativo en la cantidad de código de máquina en comparación con los lenguajes que tienen un verdadero sistema de tipos polimórficos (descendientes de ML ). Para reducir el tamaño del código de máquina, intentan procesar automáticamente el código fuente antes de la etapa de desenrollado de plantillas [46] [47] . Otra solución podría ser la capacidad de exportar plantillas, que se estandarizó en 1998, pero no está disponible en todos los compiladores, ya que es difícil de implementar [48] [49] [opiniones 4] y para importar bibliotecas de plantillas C ++ a idiomas con una semántica de C++ significativamente diferente, seguiría siendo inútil. Los defensores de C++ cuestionan el grado de exceso de código como exagerado [50] , e incluso ignoran el hecho de que en C el polimorfismo paramétrico se traduce directamente, es decir, sin duplicar cuerpos de funciones en absoluto. Al mismo tiempo, los partidarios de C++ creen que el polimorfismo paramétrico en C es peligroso, es decir, más peligroso que la transición de C a C++ (los que se oponen a C++ argumentan lo contrario, véase más arriba).
Potencial de optimizaciónDebido al sistema de tipo débil y la abundancia de efectos secundarios , se vuelve extremadamente difícil convertir programas de manera equivalente y, por lo tanto, incorporar muchos algoritmos de optimización en el compilador, como la paralelización automática de programas , la eliminación de subexpresiones comunes , λ-lifting, llamadas a procedimientos con paso de continuación , supercompilación , etc. Como resultado, la efectividad real de los programas de C++ está limitada por las habilidades de los programadores y los esfuerzos invertidos en un proyecto en particular, y una implementación "descuidada" puede ser significativamente inferior en eficiencia a "descuidada". ” implementaciones en lenguajes de nivel superior, lo que se confirma mediante pruebas comparativas de lenguajes [34] . Esta es una barrera significativa contra el uso de C++ en la industria de minería de datos .
Gestión eficiente de la memoriaLa responsabilidad de una gestión eficaz de la memoria recae sobre los hombros del desarrollador y depende de sus habilidades. Para la gestión automática de la memoria en C ++, los llamados. "punteros inteligentes", la gestión manual de la memoria reduce la eficiencia de los propios programadores (consulte la sección Eficiencia ) . Numerosas implementaciones de recolección de elementos no utilizados , como la inferencia estática de regiones , no son aplicables a los programas C++ (más precisamente, esto requiere la implementación de un nuevo intérprete de lenguaje además del lenguaje C++, que es muy diferente de C++ tanto en la mayoría de las propiedades objetivas y en general ideología) debido a la necesidad de acceso directo a AST .
La correlación de los factores de desempeño con los costos de desarrollo, así como la disciplina general y la cultura de programación cultivada en la comunidad de programación, son importantes para los clientes que eligen un lenguaje (y, en consecuencia, prefieren este lenguaje de desarrolladores) para la implementación de sus proyectos. así como para personas que comienzan a aprender programación, especialmente con la intención de programar para sus propias necesidades.
Calidad y cultura de la programaciónEl principio de C++ " de no imponer un" buen "estilo de programación " es contrario al enfoque industrial de la programación, en el que el papel principal lo juega la calidad del software y la posibilidad de mantener el código no solo por parte del autor. , y para los que se prefieren lenguajes que minimicen la influencia del factor humano , es decir, simplemente " imponer un 'buen' estilo de programación ", aunque dichos lenguajes pueden tener un umbral de entrada más alto.
Existe la opinión de que la preferencia por utilizar C++ (con la posibilidad de elegir lenguajes alternativos) caracteriza negativamente las cualidades profesionales de un programador. Específicamente, Linus Torvalds dice que usa las opiniones positivas de los candidatos sobre C++ como criterio de abandono [opiniones 3] :
C++ es un lenguaje terrible. Lo que lo hace aún más horrendo es el hecho de que muchos programadores analfabetos lo usan... Francamente, incluso si no hay razón para elegir C aparte de mantener alejados a los programadores de C++, eso por sí solo sería una buena razón para usar C.
…He llegado a la conclusión de que realmente preferiría echar a cualquiera que prefiera desarrollar un proyecto en C++ que en C, para que esa persona no arruine el proyecto en el que estoy involucrado.
La evolución continua del lenguaje alienta (ya veces obliga) a los programadores a cambiar el código ya depurado una y otra vez; esto no solo aumenta el costo de desarrollo, sino que también conlleva el riesgo de introducir nuevos errores en el código depurado. En particular, aunque la compatibilidad con versiones anteriores de C fue originalmente uno de los principios básicos de C++, desde 1999 C dejó de ser un subconjunto de C++, por lo que el código C depurado ya no se puede usar en un proyecto de C++ sin modificaciones.
Complejidad por sí mismaC++ es definido por sus apologistas como "el más poderoso" precisamente porque está repleto de características peligrosas y mutuamente contradictorias. Según Eric Raymond , esto convierte al propio lenguaje en un terreno de autoafirmación personal de los programadores, convirtiendo el proceso de desarrollo en un fin en sí mismo:
Los programadores suelen ser individuos extravagantes que se enorgullecen de... su capacidad para manejar la complejidad y las abstracciones con destreza. A menudo compiten entre sí, tratando de descubrir quién puede crear "las complejidades más intrincadas y hermosas". ... los rivales creen que deben competir con las "decoraciones" de otras personas agregando las suyas propias. Muy pronto, el "tumor masivo" se convierte en el estándar de la industria, y todo el mundo ejecuta grandes programas con errores que ni siquiera sus creadores pueden satisfacer.
…
… este enfoque puede causar problemas si los programadores hacen cosas simples de formas complejas, simplemente porque conocen esas formas y saben cómo usarlas.
Se han notado casos en los que programadores descuidados, utilizando la fuerte dependencia del contexto de C ++ y la falta de capacidad para rastrear definiciones de macro por parte del compilador, ralentizaron el desarrollo del proyecto escribiendo uno o dos adicionales, correctos desde el punto de vista del compilador. de vista, líneas de código, pero introduciendo un error manifestado espontáneamente difícil de detectar a su costa. Por ejemplo:
#define si(a) si(al azar())En lenguajes con corrección comprobada , incluso con facilidades de macros avanzadas, es imposible hacer daño de esta manera.
Producto poco fiableUna abundancia irrazonable de efectos secundarios, combinada con la falta de control del sistema de tiempo de ejecución del lenguaje y un sistema de tipo débil, hace que los programas de C++ sean propensos a fallas fatales impredecibles (las conocidas fallas con mensajes como "Violación de acceso", "Función virtual pura call" o "El programa realizó una operación ilegal y se cerrará"), lo que excluye el uso de C ++ con altos requisitos de tolerancia a fallas. Además, aumenta la duración del propio proceso de desarrollo [34] .
Gestión de proyectosLos factores enumerados anteriormente hacen que la complejidad de la gestión de proyectos de C++ sea una de las más altas en la industria del desarrollo de software.
James Coggins, columnista de The C++ Report durante cuatro años , explica:
El problema es que los programadores de programación orientada a objetos han estado experimentando con aplicaciones incestuosas y apuntando a un bajo nivel de abstracción. Por ejemplo, crearon clases como "lista enlazada" en lugar de "interfaz de usuario" o "haz de radiación" o "modelo de elementos finitos". Desafortunadamente, la verificación de tipo fuerte, que ayuda a los programadores de C++ a evitar errores, también dificulta la creación de objetos grandes a partir de objetos pequeños.
El único descendiente directo de C++ es el lenguaje D , destinado a ser una reelaboración de C++ para abordar sus problemas más obvios. Los autores abandonaron la compatibilidad con C, conservando la sintaxis y muchos de los principios básicos de C ++ e introduciendo funciones en el lenguaje que son características de los nuevos lenguajes. D no tiene preprocesador, ni archivos de encabezado, ni herencia múltiple, sino un sistema de módulos, interfaces, arreglos asociativos, soporte para Unicode en cadenas, recolección de elementos no utilizados (manteniendo la posibilidad de administración manual de la memoria), subprocesos múltiples incorporados, inferencia de tipos , declaración explícita de funciones puras y valores inmutables. El uso de D es muy limitado, no puede considerarse un competidor real de C ++.
El competidor más antiguo de C++ en tareas de bajo nivel es Objective-C , también basado en el principio de combinar C con un modelo de objetos, solo el modelo de objetos se hereda de Smalltalk . Objective-C, al igual que su descendiente Swift , se usa ampliamente para el desarrollo de software para macOS e iOS.
Una de las primeras alternativas a C++ en la programación de aplicaciones fue el lenguaje Java . A menudo se considera erróneamente un descendiente directo de C++; de hecho, la semántica de Java se hereda del lenguaje Modula-2 y la semántica básica de C++ no se puede rastrear en Java. Dado esto, y la genealogía de los lenguajes (Modula-2 es un descendiente de Simula , como C++, pero no es C), Java es más correctamente llamado el " primo segundo " de C++, en lugar del " heredero ". Lo mismo puede decirse del lenguaje C# , aunque el porcentaje de afinidad con C++ es ligeramente superior al de Java.
Un intento de combinar la seguridad y la velocidad de desarrollo de Java y C# con las capacidades de C++ fue el dialecto de C++ administrado (posteriormente C++/CLI ). Fue desarrollado por Microsoft principalmente para trasladar proyectos C++ existentes a la plataforma Microsoft .NET. Los programas se ejecutan bajo CLR y pueden usar la matriz completa de bibliotecas .NET, pero hay una serie de restricciones en el uso de funciones de C++, lo que reduce efectivamente C++ a C#. Este dialecto no ha recibido un amplio reconocimiento y se utiliza principalmente para vincular bibliotecas escritas en C ++ puro con aplicaciones C #.
Una forma alternativa de desarrollar el lenguaje C es combinarlo no con la programación orientada a objetos, sino con la programación aplicativa , es decir, mejorando la abstracción, el rigor y la modularidad de los programas de bajo nivel proporcionando un comportamiento predecible y transparencia referencial . Ejemplos de trabajo en esta línea son los lenguajes BitC , Cyclone y Limbo . Aunque también hay intentos exitosos de usar FP en problemas en tiempo real sin integración con herramientas C [52] [53] [54] , todavía en este momento (2013) en desarrollo de bajo nivel, el uso de herramientas C hasta cierto punto tiene una mejor relación entre la intensidad del trabajo y la eficiencia. Los desarrolladores de Python y Lua han puesto mucho esfuerzo en Python y Lua para garantizar que los programadores de C++ utilicen estos lenguajes, por lo que de todos los lenguajes que están estrechamente relacionados con FP, son los que se utilizan con mayor frecuencia. Se señaló que se usa junto con C ++ en el mismo proyecto. Los puntos de contacto más significativos entre C++ y FP son los enlaces de bibliotecas wxWidgets y Qt desarrollados en C++ con una ideología específica de C++ a Lisp , Haskell y Python (en la mayoría de los casos, los enlaces a lenguajes funcionales se realizan para bibliotecas escritas en C u otros lenguajes funcionales).
Otro lenguaje considerado competidor de C++ es Nemerle , que es el resultado de un intento de combinar el modelo de escritura Hindley-Milner y un subconjunto de macros de Common Lisp con C# [55] . En la misma línea está F# de Microsoft , un dialecto de ML adaptado para el entorno .NET.
Un intento de crear un reemplazo industrial para C / C ++ fue el lenguaje de programación Go desarrollado por Google en 2009 . Los autores del lenguaje señalan directamente que el motivo de su creación fueron las deficiencias del proceso de desarrollo provocadas por las peculiaridades de los lenguajes C y C++ [56] . Go es un lenguaje imperativo compacto y sin complicaciones con sintaxis similar a C, sin preprocesador, escritura estática, escritura fuerte, sistema de empaquetado, administración automática de memoria, algunas características funcionales, subsistema OOP construido económicamente sin soporte para herencia de implementación, pero con interfaces y escritura pato , subprocesos múltiples incorporados basados en corrutinas y tuberías (a-la Occam ). El lenguaje se posiciona como una alternativa a C ++, es decir, ante todo, un medio para el desarrollo grupal de sistemas informáticos altamente complejos, incluidos los distribuidos, que permiten, si es necesario, una programación de bajo nivel.
En el mismo nicho ecológico con C/C++ está Rust, desarrollado en 2010 y mantenido por Mozilla Corporation , centrado en la gestión segura de la memoria sin el uso de un recolector de basura . En particular, los planes para reemplazar parcialmente C / C ++ con Rust fueron anunciados en 2019 por Microsoft [57] .
diccionarios y enciclopedias | ||||
---|---|---|---|---|
|
Lenguajes de programación | |
---|---|
|
ISO | Normas|
---|---|
| |
1 a 9999 |
|
10000 a 19999 |
|
20000+ | |
Ver también: Lista de artículos cuyos títulos comienzan con "ISO" |
C++ | |
---|---|
Peculiaridades | |
algunas bibliotecas | |
compiladores | |
influenciado | |
|