una primer obtener funciones dev declarar caracteres caracter cadenas cadena arreglo c++ string immutability

primer - string dev c++



cadenas inmutables vs std:: cadena (11)

Recientemente he estado leyendo acerca de cadenas inmutables, here y here también algunas cosas sobre por qué D eligió cadenas inmutables. Parece que hay muchas ventajas.

  • trivialmente hilo seguro
  • más seguro
  • más eficiente con la memoria en la mayoría de los casos de uso.
  • subcadenas baratas (tokenización y corte)

Sin mencionar que la mayoría de los nuevos lenguajes tienen cadenas inmutables, D2.0, Java, C #, Python, etc.

¿Se beneficiaría C ++ de las cadenas inmutables?

¿Es posible implementar una clase de cadena inmutable en c ++ (o c ++ 0x) que tenga todas estas ventajas?

actualizar:

Hay dos intentos de cadenas inmutables const_string y fix_str . Ninguno ha sido actualizado en media década. ¿Incluso se usan? ¿Por qué no const_string alguna vez lo hizo en impulso?


Ciertamente no eres la única persona que pensó eso. De hecho, hay const_string biblioteca const_string de Maxim Yegorushkin, que parece haber sido escrita teniendo en cuenta la inclusión en boost. Y aquí hay una biblioteca más nueva, fix_str de Roland Pibinger. No estoy seguro de qué tan complicado sería el interinato de cadena completo en el tiempo de ejecución, pero la mayoría de las ventajas se pueden lograr cuando sea necesario.


Como una opinión:

  • Sí, me gustaría bastante una biblioteca de cadenas inmutables para C ++.
  • No, no me gustaría que std :: string sea inmutable.

¿Realmente vale la pena hacerlo (como una característica estándar de la biblioteca)? Yo diría que no. El uso de const le proporciona cadenas locales inmutables, y la naturaleza básica de los lenguajes de programación de sistemas significa que realmente necesita cadenas mutables.


Descubrí que la mayoría de las personas en este hilo no entienden realmente qué es immutable_string . No se trata solo de la constness. El poder immutable_string de immutable_string es el rendimiento (incluso en el programa de un solo hilo) y el uso de la memoria.

Imagine que, si todas las cadenas son inmutables, y todas las cadenas se implementan como

class string { char* _head ; size_t _len ; } ;

¿Cómo podemos implementar una operación sub-str? No necesitamos copiar ningún char. Todo lo que tenemos que hacer es asignar la _head y la _len . Luego, la subcadena comparte el mismo segmento de memoria con la cadena fuente.

Por supuesto, no podemos implementar una cadena_mmutable solo con los dos miembros de datos. La implementación real podría necesitar un bloque de memoria contado por referencia (o ponderado). Me gusta esto

class immutable_string { boost::fly_weight<std::string> _s ; char* _head ; size_t _len ; } ;

Tanto la memoria como el rendimiento serían mejores que la cadena tradicional en la mayoría de los casos, especialmente cuando sabes lo que estás haciendo.

Por supuesto, C ++ puede beneficiarse de una cadena inmutable, y es bueno tener una. He comprobado el boost::const_string y el fix_str mencionado por Cubbi. Esos deberían ser de lo que estoy hablando.


Las cadenas de C ++ son seguras para hilos, se garantiza que todos los objetos inmutables son seguros para subprocesos pero StringBuffer de Java es mutable como la cadena de C ++ y ambos son seguros para subprocesos. ¿Por qué preocuparse por la velocidad, definir el método o los parámetros de función con la palabra clave const para decirle al compilador que la cadena será inmutable en ese ámbito? Además, si el objeto cadena es inmutable a pedido, esperando cuando es absolutamente necesario utilizar la cadena, es decir, cuando agrega otras cadenas a la cadena principal, tiene una lista de cadenas hasta que realmente necesita toda la cadena y luego se unen juntos en ese punto.

Objeto inmutable y mutable operar a la misma velocidad que yo sepa, excepto sus métodos, que es una cuestión de pro y contra. las primitivas constantes y las primitivas variables se mueven a diferentes velocidades porque a nivel de máquina, las variables se asignan a un registro o espacio de memoria que requieren algunas operaciones binarias, mientras que las constantes son etiquetas que no requieren ninguna de ellas y por lo tanto son más rápidas (o menos trabajo está hecho). funciona solo para primitivos y no para objetos.


Las cadenas inmutables son geniales si , siempre que sea necesario crear una nueva cadena, el administrador de memoria siempre podrá determinar el paradero de cada referencia de cadena. En la mayoría de las plataformas, el soporte de idiomas para dicha capacidad podría proporcionarse a un costo relativamente modesto, pero en plataformas sin dicho soporte de lenguaje incorporado es mucho más difícil.

Si, por ejemplo, uno quisiera diseñar una implementación de Pascal en x86 que admitiera cadenas inmutables, sería necesario que el asignador de cadenas recorriera la pila para encontrar todas las referencias de cadenas; el único costo de tiempo de ejecución de eso requeriría un enfoque consistente de llamada de función [por ejemplo, no usar llamadas de cola, y tener cada función no hoja mantener un puntero de cuadro]. Cada área de memoria asignada con new necesitaría tener un bit para indicar si contenía alguna cadena y la que contiene cadenas necesitaría tener un índice para un descriptor de disposición de memoria, pero esos costos serían bastante pequeños.

Si un GC no era una tabla para recorrer la pila, entonces sería necesario tener identificadores de uso de código en lugar de punteros, y tener código crear identificadores de cadena cuando las variables locales entren en el alcance y destruir los identificadores cuando salgan del alcance. Mucho mayor sobrecarga.


Las cadenas son mutables en Ruby.

$ irb >> foo="hello" => "hello" >> bar=foo => "hello" >> foo << "world" => "helloworld" >> print bar helloworld=> nil

  • trivialmente hilo seguro

Tiendo a olvidar los argumentos de seguridad. Si quieres estar seguro para subprocesos, bloquéalo o no lo toques. C ++ no es un lenguaje conveniente, tiene sus propias convenciones.

  • más seguro

No. Tan pronto como tenga aritmética de puntero y acceso desprotegido al espacio de direcciones, olvídese de estar seguro. Más seguro contra la codificación inocentemente malo, sí.

  • más eficiente con la memoria en la mayoría de los casos de uso.

A menos que implemente mecanismos intensivos en CPU, no veo cómo.

  • subcadenas baratas (tokenización y corte)

Ese sería un muy buen punto. Podría hacerse al referirse a una cadena con referencias hacia atrás, donde las modificaciones a una cadena causarían una copia. Tokenizar y rebanar se vuelven libres, las mutaciones se vuelven costosas.


Mi conclusión es que C ++ no requiere el patrón inmutable porque tiene semántica const.

En Java, si tiene una clase Person y devuelve el String name de la persona con el método getName() , su única protección es el patrón inmutable. Si no estuviera allí, tendría que clone() sus cadenas todo el día y la noche (como lo tiene que hacer con los miembros de datos que no son objetos de valor típicos, pero que aún necesitan protección).

En C ++ tienes const std::string& getName() const . Entonces puede escribir SomeFunction(person.getName()) donde es como void SomeFunction(const std::string& subject) .

  • No hubo copia
  • Si alguien quiere copiar, es libre de hacerlo
  • La técnica se aplica a todos los tipos de datos, no solo a cadenas

No creo que haya una respuesta definitiva aquí. Es subjetivo, si no es por gusto personal, al menos por el tipo de código con el que uno más a menudo trata. (Aún así, una pregunta valiosa)

Las cadenas inmutables son excelentes cuando la memoria es barata; esto no era así cuando se desarrolló C ++, y no es el caso en todas las plataformas a las que se dirige C ++. (OTOH en plataformas más limitadas C parece mucho más común que C ++, por lo que ese argumento es débil.)

Puede crear una clase de cadena inmutable en C ++, y puede hacer que sea ampliamente compatible con std::string pero aún perderá al compararlo con una clase de cadena incorporada con optimizaciones dedicadas y funciones de idioma.

std::string es la mejor cadena estándar que tenemos, así que no me gustaría ver ningún problema con ella. Sin embargo, lo uso muy raramente; std::string tiene demasiados inconvenientes desde mi punto de vista .


Qt también usa cadenas inmutables con copy-on-write.
Existe cierto debate sobre cuánto rendimiento realmente te compra con compiladores decentes.


las cadenas constantes tienen poco sentido con la semántica de valores, y compartir no es una de las mayores fortalezas de C ++ ...


const std::string

Ahí tienes. Un literal de cadena también es inmutable, a menos que desee obtener un comportamiento indefinido.

Editar: por supuesto, eso es solo la mitad de la historia. Una variable de cadena const no es útil porque no se puede hacer referencia a una nueva cadena. Una referencia a una cadena const lo haría, excepto que C ++ no le permitirá reasignar una referencia como en otros lenguajes como Python. Lo más parecido sería un puntero inteligente a una cadena asignada dinámicamente.