¿Cómo se implementa std::string?


Tengo curiosidad por saber cómo se implementa std::string y en qué se diferencia de la cadena c?Si el estándar no especifica ninguna implementación, entonces cualquier implementación con explicación sería excelente con la forma en que satisface el requisito de cadena dado por el estándar?

Author: yesraaj, 2009-09-23

5 answers

Prácticamente todos los compiladores que he usado proporcionan código fuente para el tiempo de ejecución, así que ya sea que esté usando GCC o MSVC o lo que sea, tiene la capacidad de mirar la implementación. Sin embargo, una gran parte o la totalidad de std::string se implementará como código de plantilla, lo que puede hacer que la lectura sea muy difícil.

El libro de Scott Meyer, Effective STL, tiene un capítulo sobre las implementaciones de std:: string que es una descripción decente de las variaciones comunes: "Item 15: Be aware of variations in string aplicación".

Él habla de 4 variaciones:

  • Varias variaciones en una implementación ref-counted (comúnmente conocida como copy on write): cuando un objeto de cadena se copia sin cambios, el refcount se incrementa, pero los datos de cadena reales no. Ambos objetos apuntan a los mismos datos recontados hasta que uno de los objetos los modifica, causando una 'copia al escribir' de los datos. Las variaciones están en donde se almacenan cosas como el refcount, bloqueos, etc.

  • A implementación de" optimización de cadenas cortas " (SSO). En esta variante, el objeto contiene el puntero habitual a los datos, longitud, tamaño del búfer asignado dinámicamente, etc. Pero si la cadena es lo suficientemente corta, usará esa área para mantener la cadena en lugar de asignar dinámicamente un búfer

También, el "C++más excepcional"de Herb Sutter tiene un apéndice (Apéndice A: "Optimizaciones que no son (en un Mundo Multihilo)") que discute por qué copy on write refcounted las implementaciones a menudo tienen problemas de rendimiento en aplicaciones multiproceso debido a problemas de sincronización. Ese artículo también está disponible en línea (pero no estoy seguro de si es exactamente lo mismo que lo que está en el libro):

Ambos capítulos valdría la pena leerlos.

 70
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-26 11:55:39

Std::string es una clase que envuelve algún tipo de búfer interno y proporciona métodos para manipular ese búfer.

Una cadena en C es solo una matriz de caracteres

Explicar todos los matices de cómo funciona std::string aquí llevaría demasiado tiempo. Tal vez echar un vistazo al código fuente de gcc http://gcc.gnu.org para ver exactamente cómo lo hacen.

 11
Author: Glen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-23 13:46:21

Hay una implementación de ejemplo en una respuesta en esta página.

Además, puede mirar la implementación de gcc, asumiendo que tiene gcc instalado. Si no, puede acceder a su código fuente a través de SVN. La mayor parte de std::string está implementado por basic_string , así que comienza allí.

Otra posible fuente de información es El compilador de Watcom

 6
Author: DVK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-23 13:55:36

La solución c++ para cadenas es bastante diferente de la versión c. La primera y más importante diferencia es que mientras la c usa la solución ASCIIZ, la std:: string y std::wstring usan dos iteradores (punteros) para almacenar la cadena real. El uso básico de las clases de cadena proporciona una solución de asignación dinámica, por lo que en el costo de la sobrecarga de la CPU con el manejo de memoria dinámica hace que el manejo de cadena sea más cómodo.

Como probablemente ya sabes, la C no contiene cualquier tipo de cadena genérico incorporado, solo proporciona un par de operaciones de cadena a través de la biblioteca estándar. Una de las principales diferencias entre C y C++ es que el C++ proporciona una funcionalidad empaquetada, por lo que puede considerarse como un tipo genérico falso.

En C necesitas recorrer la cadena si quieres saber su longitud, la función miembro std::string::size() es básicamente una sola instrucción (end - begin). Puede anexar cadenas de forma segura una a otra, siempre y cuando tiene memoria, por lo que no hay necesidad de preocuparse por los errores de desbordamiento de búfer (y por lo tanto los exploits), porque el anexado crea un búfer más grande si es necesario.

Como alguien dijo aquí antes, la cadena se deriva de la funcionalidad vectorial, de una manera templada, por lo que hace más fácil tratar con los sistemas de caracteres multibyte. Puede definir su propio tipo de cadena usando la expresión typedef std:: basic_string specific_str_t; con cualquier tipo de datos arbitrario en la plantilla parámetro.

Creo que hay suficientes pros y contras en ambos lados:

C++ string Pros: - Iteración más rápida en ciertos casos (usando el tamaño definitivamente, y no necesita los datos de la memoria para verificar si está al final de la cadena, comparando dos punteros. eso podría hacer una diferencia con el almacenamiento en caché) - La operación del búfer está llena de la funcionalidad de cadena, por lo que menos preocupaciones sobre los problemas del búfer.

C++ string Cons: - debido a la memoria dinámica cosas de asignación, el uso básico podría causar un impacto en el rendimiento. (afortunadamente, puede decirle al objeto string cuál debería ser el tamaño del búfer original, por lo que a menos que lo exceda, no asignará bloques dinámicos de la memoria) - nombres a menudo extraños e inconsistentes en comparación con otros idiomas. esto es lo malo de cualquier cosa stl, pero se puede utilizar a él, y hace un poco específico C++ish sensación. - el uso intensivo de la plantilla fuerza a la biblioteca estándar a usar encabezado soluciones basadas por lo que es un gran impacto en el tiempo de compilación.

 4
Author: progician,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-23 17:32:21

Eso depende de la biblioteca estándar que utilice.

STLPort por ejemplo, es una implementación de Biblioteca estándar de C++ que implementa cadenas, entre otras cosas.

 3
Author: Georg Schölly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-23 13:49:03