2010-11-17 14 views

Respuesta

15

no se derivan de CADENA

std :: string, es decir, básicamente toda la plantilla basic_string no está diseñado para ser derivado de. Ya hay montones de artículos sobre eso. No tiene ninguna función virtual, por lo que no hay nada que anular. Lo mejor que puedes hacer es esconder algo. ¡Lo mejor es usar composición/agregación! Es decir, simplemente mantenga un miembro de tipo cadena en su clase y reenvíe las llamadas. Una vez más, sólo para asegurarse de

no se derivan de CADENA

+2

-1. La mejor práctica para esta tarea es proporcionar un objeto Character Traits y crear instancias de 'std :: basic_string'. Ocultar un 'std :: string' en este caso plantea el problema de la firma de' char', ya que UTF-8 es una codificación multibyte de 8 bits. –

+1

@larsmans: Sin objeciones :) Estaba demasiado preocupado con el hecho de que alguien en algún lugar tuvo la idea de derivar de un tipo no polimórfico :) –

+0

-1. Realmente no responde la pregunta. La respuesta de larsman al menos da una buena idea para una dirección a seguir. – leetNightshade

1
  1. ¿Has mirado en la UCI?

  2. A typedef es simplemente una etiqueta conveniente.

    clase foo: public bar {};

funciona bien cuando la barra es un typedef de un PT.

Puede que no sea una buena idea en este caso, pero el lenguaje lo admite.

4

En general, se considera un error en C++ derivar de un contenedor de biblioteca estándar. Sin embargo, la funcionalidad que está buscando ya ha sido implementada. Eche un vistazo a Glib::ustring.

Espero que esto ayude!

0

Mejor idea: crear un contenedor utf8_string compatible con STL sin heredar de std :: string.

19

Si debe definir su propio tipo cadena, entonces no heredan de std::string pero definir su propia clase Character Traits y hacer algo como

typedef std::basic_string<unsigned char, utf8_traits> utf8string; 

Ver también Herb Sutter's website.

+0

+1 - hay un motivo 'std :: string' es un' typedef', y esto es todo. –

+0

Por otro lado, no usaría 'basic_string' para manejar secuencias UTF-8. Harás más daño que bien cuando trates de manipularlo. –

+3

@Matthieu M., eso depende completamente de cómo implemente los Rasgos de carácter. Puedo ver dos opciones: empacarlos como UTF-8 directamente e implementar el 'state_type', o empaquetarlos como UTF-32 y convertirlos en el límite. De cualquier manera, es mucho trabajo, pero conserva la compatibilidad con los algoritmos STL. –

-1

Como ya se ha dicho por otros: no se deriva de std::string, simplemente no está diseñado para esto.

Debería echar un vistazo en this article, que muestra cómo crear una clase de cadena que no distinga entre mayúsculas y minúsculas como ejemplo. Verá que la lógica implementada en std::basic_string es independiente del tipo de carácter, y que proporcionar un poco de char_traits personalizado debería ser el truco.

+1

En realidad, no recomendaría hacer esto. Hice esto hace unos años y tuve que lamentar esa decisión. Lo que sucederá es que tendrá que realizar conversiones de ida y vuelta entre este nuevo tipo y el tipo de cadena estándar, en todo su código base. No es lindo. Un gran artículo que explica en detalle se encuentra aquí: http://lafstern.org/matt/col2_new.pdf. Resumen: la insensibilidad a un caso no se trata de un objeto, se trata de cómo se usa un objeto. –

0

Escribir una implementación unicode que se ajuste y funcione correctamente en cada circunstancia es muy difícil de hacer. Le aconsejo que use una biblioteca o implementación existente en lugar de desplegar la suya propia. Por ejemplo, Windows, OSX y Qt tienen bibliotecas que admiten UTF-16 y otras cadenas codificadas.

1

Solo asegúrese de saber lo que está haciendo primero. ¿Cuál es exactamente la "longitud correcta" que desea devolver de sus objetos de cadena? Número de puntos de código?Eso no siempre se corresponde con la cantidad de caracteres que percibe el usuario.

De todos modos, eche un vistazo a la biblioteca utf8-cpp para ver un enfoque alternativo para derivar de std :: string.

Cuestiones relacionadas