Bienvenidos sean a mi post, hoy hablaremos sobre un tema pendiente del post de Arrays, clases de cadenas.
Como dijimos en ese momento, las clases de C no estan orientadas a objetos y muchas veces terminaremos creando las nuestras, veamos un ejemplo y desarrollemoslo:
string.cpp
# include <iostream>
# include <string.h>
using namespace std;
class String
{
public:
String();
String(const char * const);
String(const String & );
~String();
char & operator[] (unsigned short offset );
char operator[] (unsigned short offset) const;
String operator+ (const String & );
void operator+= (const String & );
String & operator= (const String & );
unsigned short GetLen() const { return itsLen; }
const char * GetString() const { return itsString; }
private:
String(unsigned short);
char * itsString;
unsigned short itsLen;
};
String::String()
{
itsString = new char[ 1 ];
itsString[ 0 ] = '\0';
itsLen = 0;
}
String::String(unsigned short len)
{
itsString = new char[ len + 1 ];
for(unsigned short i = 0; i <= len; i++)
itsString[ i ] = '\0';
itsLen = len;
}
String::String(const char * const cString)
{
itsLen = strlen(cString);
itsString = new char[ itsLen + 1 ];
for(unsigned short i = 0; i < itsLen; i++ )
itsString[ i ] = cString[ i ];
itsString[ itsLen ] = '\0';
}
String::String(const String & rhs )
{
itsLen = rhs.GetLen();
itsString = new char[ itsLen + 1 ];
for(unsigned short i = 0; i < itsLen; i++)
itsString[ i ] = rhs[ i ];
itsString[ itsLen ] = '\0';
}
String::~String()
{
delete [] itsString;
itsLen = 0;
}
String & String :: operator= (const String & rhs)
{
if (this == &rhs)
return *this;
delete [] itsString;
itsLen = rhs.GetLen();
itsString = new char[ itsLen + 1 ];
for(unsigned short i = 0; i < itsLen; i++)
itsString[ i ] = rhs[ i ];
itsString[ itsLen ] = '\0';
return *this;
}
char & String::operator[] (unsigned short offset)
{
if (offset > itsLen)
return itsString[ itsLen - 1 ];
else
return itsString[ offset ];
}
char String::operator[] (unsigned short offset) const
{
if (offset > itsLen)
return itsString[ itsLen - 1 ];
else
return itsString[ offset ];
}
String String::operator+ (const String & rhs)
{
unsigned short totalLen = itsLen + rhs.GetLen();
String temp(totalLen);
unsigned short i;
for (i=0; i < itsLen; i++)
temp[ i ] = itsString[ i ];
for (unsigned short j = 0; j < rhs.GetLen(); j++ , i++)
temp[ i ] = rhs[ j ];
temp[ totalLen ] = '\0';
return temp;
}
void String::operator+= (const String & rhs)
{
unsigned short rhsLen = rhs.GetLen();
unsigned short totalLen = itsLen + rhsLen;
String temp(totalLen);
unsigned short i;
for(i = 0; i < itsLen; i++)
temp[ i ] = itsString[ i ];
for(unsigned short j=0; j < rhs.GetLen(); j++, i++)
temp[ i ] = rhs[ i - itsLen ];
temp[totalLen] = '\0';
*this = temp;
}
int main()
{
String s1("Prueba Inicial");
cout << "S1: \t\t" << s1.GetString() << endl;
char temp[] = "Hola, Mundo!";
s1 = temp;
cout << "S1: \t\t" << s1.GetString() << endl;
char tempDos[ 26 ];
strcpy(tempDos,"; Es grandioso estar aqui!");
s1 += tempDos;
cout << "tempDos: \t" << tempDos << endl;
cout << "S1: \t\t" << s1.GetString() << endl;
cout << "S1[ 3 ]: \t" << s1[ 3 ] << endl;
s1[ 3 ] = 'x';
cout << "S1: \t\t" << s1.GetString() << endl;
cout << "S1[999]: \t" << s1[ 999 ] << endl;
String s2("Otra cadena");
String s3;
s3 = s1 + s2;
cout << "S3: \t\t" << s3.GetString() << endl;
String s4;
s4="Por que trabaja esta funcion???";
cout << "S4: \t\t" << s4.GetString() << endl;
return 0;
}
Este es un programa simple encargado de recibir unas cadenas de texto y efectua algunas operaciones con las mismas, primero tenemos la clase String, en esta no solamente vamos a tener los constructores y destructores sino tambien los operadores para poder manipular los objetos creados a partir de esta clase, los operadores ha utilizar van a ser corchetes ([]) tambien llamado operador de desplazamiento, el operador suma (+), el operador igual (=) y el operador suma-igual (+=) para ver en mas detalle la definicion de operadores de clases les recomiendo este post. Tambien vamos a tener dos metodos de la clase, uno va a ser GetLen(), va a ser utilizado para obtener el tamaño de la cadena, y la otra va a ser GetString() el cual nos va a permitir obtener el contenido almacenado de la cadena en la parte privada de la clase.
En este caso vamos a utilizar sobrecarga de Constructores, tambien para el operador de desplazamiento ([]), primero vamos a crear el constructor predeterminado, luego vamos a crear un constructor privado, para ser utilizado como un asistente para los metodos de la clase y esta nos va a permitir crear una cadena nueva del tamaño requerido, despues sigue el constructor encargado de convertir el array de caracteres en una cadena, luego definimos el constructor de copia, y para finalizar el destructor, el encargado de eliminar todas las copias creadas de itsString y liberar a itsLen.
Pasemos a las funciones de los operadores, en el primer caso tenemos el igual (=), cuando recibe el valor a traves de rhs, este lo compara con el valor del apuntador this, de ser iguales devuelve el valor de this, en caso contrario libera la memoria, y luego vuelve a copiar el contenido y el tamaño para finalmente retornarlo a traves de this (y este va a tener un nuevo valor), despues vamos a definir el opeador de desplazamiento ([]) no constante, el cual nos va a permitir modificar un caracter de la referencia, luego vamos a declarar otro operador de desplazamiento pero esta vez es constante, para poder utilizarlo con objetos const, en ambos casos si se fijan podran ver un condicional en el caso de que offset sea mayor al valor de itsLen retorna el valor en itsString con la posicion itsLen -1, para evitar un desbordamiento del array y de caso contrario devuelve la posicion indicada, esto lo veremos mejor cuando mostremos la salida del programa, pasemos al siguiente operador en este caso suma (+), este va a ser el encargado de sumar (o concatenar) dos cadenas distintas y por ultimo el operador suma-igual, este nos va a permitir adicionar un nuevo valor al valor del objeto a la izquierda y luego reemplazar el valor en la misma, pasemos al main para ver como funciona el programa.
Primero creamos un objeto de clase String llamado s1, y lo vamos a iniciar con un valor, luego procedemos a mostrarlo en pantalla, despues creamos una variable temp de tipo char donde tambien la iniciamos con otro valor, y ese valor los asignamos a s1, hacemos un chequeo y veremos el cambio de cadena, luego creamos una variable tempDos con un tamaño de 26 posiciones, le efectuamos un strcpy para agregarle a su contenido una nueva informacion, despues utilizamos el operador suma-igual (+=) para adicionar al valor de s1 la informacion de tempDos, chequeamos primero el valor de tempDos y luego el de s1, ahora vamos a probar con los operadores de posicion ([]) en este caso le vamos a solicitar el caracter de la posicion cuatro (recuerden que los arrays empiezan de cero), lo muestre en pantalla para luego hacer el reemplazo del caracter en esa posicion con x, volvemos a mostrarlo para chequear el cambio, ahora vamos a probar lo mencionado cuando hablabamos de los constructores, vamos a poner un numero de posicion grande para mostrar en pantalla el resultado. Ahora crearemos dos nuevos objetos de la clase String, s2 el cual vamos a inicializar y s3 sin ningun valor, luego asignaremos a s3 el valor de la concatenacion, operador suma(+), de s1 con s2 y mostramos en pantalla el resultado para finalmente crear el objeto s4 sin valor inicial, luego asignarle una cadena y mostrarla en pantalla, la salida del programa es asi:
tinchicus@dbn001dsk:~/lenguaje/c++$ ./string S1: Prueba Inicial S1: Hola, Mundo! tempDos: ; Es grandioso estar aqui! S1: Hola, Mundo!; Es grandioso estar aqui! S1[ 3 ]: a S1: Holx, Mundo!; Es grandioso estar aqui! S1[999]: ! S3: Holx, Mundo!; Es grandioso estar aqui!Otra cadena S4: Por que trabaja esta funcion??? tinchicus@dbn001dsk:~/lenguaje/c++$
Observen como fueron trabajando los distintos operadores, entre ellos el de posicion el cual ante un valor superior al tamaño de su array nos devolvio el ultimo caracter anterior al valor nulo de la cadena. Como vemos esto se puede tornar una practica muy habitual porque en nuestros casos vamos a necesitar efectuar manipulaciones mas alla de lo disponible con C++, especialmente con lo relacionado a objetos.
En resumen, hoy hemos visto la cadena de caracteres, como trabaja, para que sirve, como crear una propia, como sobrecargar y redefinir algunos operadores, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.


Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.50