Estoy haciendo una clase de strings. El problema viene cuando quiero hacer lo siguiente;
CXString a,b,c;
a=b+c;
La definición friend es la siguiente:
CXString operator+(const CXString &s1,const CXString &s2)
{
CXString cus;
cus = s1;
cus += s2;
return cus;
}
El PROBLEMA es que se llama al destructor de la clase CXString al hacer el return, y por tanto al volver a la línea de llamada, el programa da un error de memoria inválida y todo esto.
¿Cómo debe hacerlo ?
La función está bien (bueno, yo pondría como valor de retorno 'const CXString' para evitar cosas como (b+c)=a; ). Lo que puede fallar es cómo tengas implementado el constructor copia y el operador de asignación (cuidado con la memoria dinámica...)
Para estas cosas viene muy bien el "Effective C++" de Scott Meyers.
P.D.¿Por qué no usas las STL? :ojo:
Tengo implementado:
CXString &CXString::operator =(const CXString &origen)
Donde reservo la memoria necesaria.
Pero me da la sensación de que me falta otro, que es precisamente el que el compilador debe utilizar en estos casos.¿Sabes cual es?
Por cierto, QUERRIA utilizar la clase string, pero no sé que include añadir.¿Sabes en cual se encuentra?
Gracias
El error viene por no tener implementado el contructor copia:
CXString::CXString(const CXString &);
El compilador crea por defecto un constructor copia que realiza una copia bit a bit. Al hacer el 'return cus;' se invoca al constructor copia y de ahí tu puntero perdido. Debes crear tu propio constructor copia que realice lo necesario para tu clase. Siempre que se use memoria dinámica en una clase hay que tener cuidado con los constructores, el operador asignación y el destructor.
Además, en este caso, te permite construir el objeto temporal con la otra cadena y eliminas una construcción por defecto innecesaria.
const CXString operator+(const CXString &s1,const CXString &s2)
{
CXString cus(s1);
cus += s2;
return cus;
}
Para usar la clase string de las STL usa:
#include
Si estas escribiendo contenedores y algoritmos a lo mejor deberías echarle un vistazo antes a las STL :ojo:
[ Este Mensaje fue editado por: DrDelete el 2002-04-01 14:26 ]
Muchísimas gracias..¡funciona! Y además entiendo el error, con lo que el aprendizaje es mucho mayor.
Respecto a las STL, hago el include que tu me dices y defino lo siguiente:
string prueba;
Y el compilador me dice que no entiende la variable string.¿Qué me falta añadir?
Todos los contenedores están dentro del namespace 'std' así que tienes tres opciones:
1) Indicarlo simpre que accedas:
std::string prueba;
2) Usar el namespace completo:
using namespace std;
3) Usar solo la clase:
using std::string;
Me da el siguiente error al usar:
std::string prueba;
error C2653: 'std' : is not a class or namespace name
Y al usar:
using namespace std;
El error es:
'std' : does not exist or is not a namespace
Supongo que por suspuesto habrás puesto antes el #include (es que tiene toda la pinta de que no lo hayas puesto :ojo:)
¿Tienes instaladas las STL? Creo que la implementación que viene con el Visual C++ 4-6 da problemas al no soportar "member function templates". No estoy seguro porque yo he usado siempre STLPort. ¿Alguien lo sabe con certeza?
Hi.
Yo uso string (además de vector y map) sin problemas con Visual C++ 6.
Para utilizarlas simplemente uso:
#include <string>
using namespace std;
string sCadena;
Byez.
[ Este Mensaje fue editado por: NeLo el 2002-04-01 17:33 ]
Creo recordar que el problema, al no tener funciones miembro templates, se da, por ejemplo, al intentar hacer:
list
l;
l.assign(l.rbegin(), l.rend());
que es completamente válido pero la implementación por defecto de MSVC4-6 lo da como error o:
vector v;
v.insert(v.end(), l.begin(), l.end());
también lo niega...
No me jugaría el cuello pero creo que es así...
[ Este Mensaje fue editado por: DrDelete el 2002-04-01 17:45 ]