Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Devolver objetos locales

Estas en el tema de Devolver objetos locales en el foro de C/C++ en Foros del Web. Hola, soy nuevo en esto de C++ (aunque conozco C y Java), y la verdad que me esta costando asimilar ciertos conceptos. Me ha surgido ...
  #1 (permalink)  
Antiguo 02/10/2008, 04:44
 
Fecha de Ingreso: octubre-2008
Mensajes: 3
Antigüedad: 15 años, 7 meses
Puntos: 0
Devolver objetos locales

Hola, soy nuevo en esto de C++ (aunque conozco C y Java), y la verdad que me esta costando asimilar ciertos conceptos.

Me ha surgido una duda y necesito vuestra ayuda, aqui va.

Probando cosas, he descubierto que el siguiente fragmento de codigo funciona:

class ClaseEj{} //Clase vacia

ClaseEj funcion(){
ClaseEj ret; //Llama al constructor por defecto
return ret;
}

int main(...){
ClaseEj objeto=funcion();
}

Es decir, asigno a un objeto declarado en main, otro objeto que declare en una funcion y que deberia ser local.
Sin embargo, C++ no llama al destructor de ese objeto local sino que al asignarlo al objeto declarado en main me deja utilizarlo fuera de su ambito.
Nota: (He comprobado que ni siquiera hay llamadas al operador= o al constructor copia de ClaseEj)

Incluso si cambiamos el codigo de main por:

int main(...){
ClaseEj objeto;
objeto=funcion();
}

Tambien funciona, en este caso llamando al operator= y copiando el objeto local en el objeto declarado en main, para una vez copiado, destruirlo.

La duda es: ¿Este funcionamiento es "lo normal" en C++ o es un apaño del compilador y por tanto no se puede esperar el mismo comportamiento siempre?

Muchas gracias, un saludo.
  #2 (permalink)  
Antiguo 02/10/2008, 09:06
 
Fecha de Ingreso: noviembre-2003
Ubicación: Mexico
Mensajes: 1.081
Antigüedad: 20 años, 5 meses
Puntos: 7
Respuesta: Devolver objetos locales

creo que no entiendo bien tu pregunta.
Con el primer codigo, si hace las 2 llamadas a los desctructores.
Con el segndo codigo, tambien.

Prueba declarando tu clase asi:
Código:
class ClaseEj
{
public:
	ClaseEj() { cout << "llamada al constructor" << endl; }
	~ClaseEj() { cout << "llamda al destructor" << endl; }
};
asi verificaras cuando se llama y cuando no.
  #3 (permalink)  
Antiguo 02/10/2008, 09:18
 
Fecha de Ingreso: octubre-2008
Mensajes: 3
Antigüedad: 15 años, 7 meses
Puntos: 0
Respuesta: Devolver objetos locales

Eso lo tengo hecho en el codigo, incluso en el del operador= y el del cronstructor copia (no lo puse por resumir).
Lo que ocurre es que no se si es nomral que pueda sacar a fuera de la funcion un objeto que se creo dentro.

En este caso, en "funcion" creo un objeto llamado "ret" que segun tengo entendido, deberia destruirse al salir de la funcion, por salir fuera de su ambito.
Sin embargo, al asignarselo mediante "objeto=funcion()" a otro objeto, no se destruye (no se destruye hasta que termina el programa o lo destruyo yo mismo).

La salida que me da es:
Código:
llamada al constructor
Cuando se supone que deberia ser:
Código:
llamada al constructor
llamada al destructor
y error por asignar a "objeto" el objeto "ret" que retorna la funcion y donde fue declarado de forma local.

Se que me explico muy mal pero creo que se puede entender...

Última edición por adryande; 02/10/2008 a las 09:34
  #4 (permalink)  
Antiguo 02/10/2008, 10:20
 
Fecha de Ingreso: octubre-2008
Mensajes: 3
Antigüedad: 15 años, 7 meses
Puntos: 0
Respuesta: Devolver objetos locales

Problema resuelto. Es una optimizacion por parte del compilador la que permite hacer esto de tal forma.

Si no hubiese esa optimizacion aun asi se podria hacer, pero implica una llamada automatica al constructor copia, ya que devolveriamos una copia global del objeto local, con lo que disminuye el rendimiento.

Ver "http://www.informit.com/articles/article.aspx?p=25033&seqNum=3"esto donde viene maravillosamente explicado (en ingles).

Última edición por adryande; 02/10/2008 a las 10:28
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:42.