sobrecarga de operador<<

Iniciado por adam96, 16 Diciembre 2010, 14:54 PM

0 Miembros y 1 Visitante están viendo este tema.

adam96

Bueenas. Estoy intentando hacer esto:


#include <iostream>
#include <string>
#include <vector>

using namespace std;

class MiClase {

private:
int num1;
int num2;

public:
MiClase(int x=0, int y=0) :
num1(x), num2(y) {}


// Getters
int getnum1(void) {
return num1;
}

int getnum2(void) {
return num2;
}
};

ostream& operator<<(ostream& os, const MiClase& miobj) {
cout << miobj.getnum1() << miobj.getnum2();
return os;
}

int main(void) {
MiClase miobj(3, 0);

cout << miobj;


return 0;
}


El error que me da:

../src/Test.cpp:29: error: passing 'const MiClase' as 'this' argument of 'int MiClase::getnum1()' discards qualifiers
../src/Test.cpp:29: error: passing 'const MiClase' as 'this' argument of 'int MiClase::getnum2()' discards qualifiers


Alguien me echa una manita?

Gracias anticipadas.

satu

Hola no estoy seguro pero creo que deberias hacerlo asi

Código (cpp) [Seleccionar]

friend ostream &operator << (ostream& os, const MiClase& miobj)
    {
    os<<miobj.num1<<miobj.num2;
    return os;
    }

pero dentro del class

Que algún experto diga por qué no funciona como él lo tiene porque yo no lo sé

Saludos
Breakbeat como forma de vida

Littlehorse

@Satu:

No, en realidad no es necesario en este caso declarar la definición junto con la declaración puesto que la definición es encontrada.

@adam96

Bienvenido al foro!
Lo que sucede es que utilizas un objeto constante que no puede ser modificado desde miembros que si pueden modificar. Cuando haces esto:

Código (cpp) [Seleccionar]

miobj.getnum1()


Estas llamando a getnum1 desde "const MiClase& miobj".
Ahora bien, para solucionarlo, basicamente el procedimiento a seguir es asegurarte que ni getnum1 ni getnum2 van a intentar modificar lo que en un principio no esta puesto para modificarse, -const- y si se esta seguro que nada se va a modificar, se declara la función de esta forma:

Código (cpp) [Seleccionar]
int getnum1(void) const {
return num1;
}

int getnum2(void) const {
return num2;
}


Que equivale a que getnum1 diga: "Envíame lo que quieras que yo no modifico nada ;D"

El código debería quedarte así:

Código (cpp) [Seleccionar]

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class MiClase {

private:
int num1;
int num2;

public:
MiClase(int x=0, int y=0) :
num1(x), num2(y) {}


// Getters
int getnum1(void) const {
return num1;
}

int getnum2(void) const {
return num2;
}
};

ostream& operator<<(ostream& os, const MiClase& miobj) {
cout << miobj.getnum1() << miobj.getnum2();
return os;
}

int main(void) {
MiClase miobj(3, 0);

cout << miobj;


return 0;
}



No lo he probado pero es seguro eso. Cualquier cosa, ya sabes.

Saludos!
An expert is a man who has made all the mistakes which can be made, in a very narrow field.

satu

Muchas gracias LH, no sabia eso. Yo aprendí haciéndolo dentro del .h y no sabia que así también podía hacerse. Gracias de nuevo.

Saludos
Breakbeat como forma de vida

adam96

Tengo mas dudas:


#include <iostream>
#include <string>
#include <vector>

using namespace std;

class MiClase {

private:
int num1;
int num2;

public:
MiClase(int x=0, int y=0) :
num1(x), num2(y) {}

MiClase& operator=(const MiClase& mib) {
num1 = 0;
num2 = 0;
num1 = mib.num1;
num2 = mib.num2;
return *this;
}

// Getters
int getnum1(void) const {
return num1;
}

int getnum2(void) const {
return num2;
}
};

ostream& operator<<(ostream& os, const MiClase& miobj) {
os << miobj.getnum1() << " " << miobj.getnum2();
return os;
}

int main(void) {
MiClase a(1, 2), b(3, 4);
cout << "Objeto a: " << a << endl;
a = a;
cout << "Objeto a despues de a = a: " << a << endl;


return 0;
}




Ese operator<< lo podría opner como método de la clase y que hiciese la misma tarea? A  mi no se me ocurre porque cout no es objeto de Miclase.

Y otra cosa:
Como hago para que en el operador de asignación detecte que se trata del mismo objeto y no lo borre.

Algo como if(*this != objeto_pasado) {el resto del codigo }
Los operadores de comparación no funcionan así :(

Gracias chic@s

Littlehorse

Buenas preguntas .

CitarEse operator<< lo podría opner como método de la clase y que hiciese la misma tarea?

No, no exactamente. Se declara como una función libre siempre que este llamando a otra función que haga la tarea, si no es el caso, se declara como friend de la clase en pos que pueda acceder a los miembros privados.


CitarComo hago para que en el operador de asignación detecte que se trata del mismo objeto y no lo borre.

Bueno podes hacer varias cosas. Realmente depende de si los usuarios de tu clase van o no van a realizar asignaciones así mismos, aunque lo ideal es pensar que siempre son capaces de hacerlo.
Si no existe la posibilidad que algo así ocurra bajo ningún aspecto, lo mas sencillo es hacer esto:

Código (cpp) [Seleccionar]
MiClase& operator=(const MiClase& mib)
{
if (this == &mib)//Mismo objeto?
return *this;//salimos...
num1 = 0;//Y si no, el resto de la logica
num2 = 0;
num1 = mib.num1;
num2 = mib.num2;
return *this;
}


ahora dependiendo de la complejidad de la clase tal vez haya que añadir bastante código extra. Realmente depende del caso en particular.

Saludos!
An expert is a man who has made all the mistakes which can be made, in a very narrow field.