Pasar clase nula a función + devolver clase nula si error ; Mejor manera

Iniciado por Kaxperday, 9 Junio 2016, 14:48 PM

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

Kaxperday

Bueno escribo por segunda vez el hilo ya que como casi siempre firefox hace cosas raísimas y pierdo todo lo anterior... :-* :-* :-* PD no tengo ni idea como llamar al hilo.

Bueno, pues quiero pasar una Clase (objeto) a una función, pero claro me interesa saber si es nula o no, ¿que haría pasarlo como puntero del tipo de la clase e igualarlo a NULL para ver si existe y trabajar con ella?, ¿o añadir un atributo a la clase llamado de tipo booleano "isNull" y comprobar ese atributo antes que trabajar con ella? (para saber si es NULL y no hay datos con los que trabajar).

En fin si lo paso como puntero tengo que instanciarlo en la heap y tengo que preocuparme por su liberación de memoria después pero puedo comprobar que es NULL rápidamente, si paso una clase con un atributo BOOLEAN isNull; tengo que mirarlo y ya está aunque no me parece buena forma de hacerlo.

¿Qué haríais vosotros en ese caso?.

Otro tema que tiene que ver:

También por ejemplo al devolver una clase, tengo una función que si falla devuelve una clase vacía (porque no me gusta trabajar con excepciones quizás debería), entonces lo que hago es que devuelva un puntero y si es NULL hubo error y no devuelve la clase, pero si funciona devuelve un puntero a la clase.

Ejemplo:


Response* ServeFile(std::string uri, Properties header)


¿Que haríais aquí también?

A: devolver un puntero y si es NULL hubo error (habrá que inicializarlo en la heap y eliminarlo posteriormente si devolvemos el objeto).

B: devolver la clase "Response" normal sin puntero pero en caso de que falle lanzar una excepción, de esta manera si hay fallo lanza excepción y no devuelve nada.

C: devolver la clase "Response" normal sin puntero pero que la devuelva como nula si hubo error, es decir que la ponga un atributo "isNull" y si es TRUE es que hubo error y está vacía y sino todo correcto.

En fin hay más métodos, se me ha ocurrido en el segundo ejemplo que la funcion devuelva un booleano sobre si hubo error o no y que la clase que devuelva en vez de devolverla (que devolvería un booleano para saer si hubo error) la reciba como referencia o con un puntero.

¿Cuál opción usaríais?. Yo creo que la opción B es la más profesional, ¿vosotros? ¿cuál es el mejor método?.

Saludos.

Edito: Espero que me entendáis lo que quiero decir XD

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

AlbertoBSD

Las opcines que planteas solucion bien tu problema.

A mi me parecen adecuadas las opciones A y B.

En la primera te preocupas por liberar la memoria y En la segunda por procesar la excepcion.

En ambas realizas algo...

La que decidas esta bien, yo en lo personal usaria la primera pero ya es decisión de cada quien.

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

ivancea96

Para evitar trabajar con excepciones, que relentizan el programa, puedes utilizar simplemente:
Código (cpp) [Seleccionar]
int ServeFile(Response& out, std::string uri, Properties header)

Un retorno que marque el error (0 si no hay, por ejemplo), y en caso de que no haya error, modificas el primer parámetro (en este caso).

Si es parte de un conjunto de funcionalidades más grande, también puedes hacer una función tipo "getLastError()", y utilizarlo así:
Código (cpp) [Seleccionar]
Response resp = serveFile();
if(getLastError()==0){
    // No error
}

Kaxperday

Vale seguramente haga lo que decís uno de los 2 es de lo que había pensado creo que lo mejor, aunque prefiero más lo segundo para así no estar jugando con la heap, simplemente pasar referencias y si hay error que la propia función devuelva en consecuencia, quizás use excepciones en casos donde realmente se puedan producir errores con mucha frecuencia o así, por completar código pues nunca uso excepciones.

De todas maneras gracias, y respecto a la primera pregunta no habeis contestado, quizás no la habéis entendido porque ni yo la entiendo a veces al leerla jajaja, os pongo un ejemplo, si hay una función que recibe estos parámetros:

Código (cpp) [Seleccionar]

void funcion(Properties headers, std::vector<BYTE> data)


Supongamos que estamos formando una http request a través de esos parámetros, si por ejemplo realizamos un GET, el campo de datos (cuerpo) estará nulo, en este caso fácilmente lo comprobamos pues al hacer data.size() y ver que es 0 sabemos que no hay datos.

Pero imaginemos al contrario, tenemos una clase headers sin nada, pues esta vez no queremos incluir headers adicionales a la http request, por lo tanto hacemos:

Código (cpp) [Seleccionar]

funcion(Properties(), data);


Habrá que comprobar que headers esta vacío, recomendaríais crear un atributo que muestre si está inicializado o pasaríais un vector y lo igualaríais a NULL, aquí creo que no hay más opciones. Está vez queremos formar el mensaje con headers vacio y solo con datos, con data era fácil llamando a data.size(), pero con otra clase cualquiera ¿que opciones hay?, solo estas, yo creo que optaría por el puntero, pero eso de la heap lo odio.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Cita de: Kaxperday en  9 Junio 2016, 17:33 PM
Habrá que comprobar que headers esta vacío

¿Qué utilizas del header? ¿Existe? Si no existe, o usas uno por defecto, o tiras error.

Por ejemplo, si Properties fuera un map<string,string>, donde la clave fuera el nombre del header:
-Cuando vayas a colocar el host, primeor lo buscas. Si noe xiste, 1 de 2: o pones el que tu programa genera, o tiras error.

La pregunta es: Si la función va a tirar error, ¿para qué le quieres pasar un valor "nulo"? En caso de que no tires error por ello, ¿para qué comprobar? Utilizas los datos que existan, y no utilizas los datos que no existan.

Y bueno, en caso de que ninguna de estas sirva, como un dato que sea opcional, pedir un puntero está bien, y no tienes porqué utilizar memoria dinámica. Basta utilizar el operador de referencia, &, a la hora de pasar el parámetro (o poner nullptr en caso de que lo quieras nulo).

Cita de: Kaxperday en  9 Junio 2016, 17:33 PM
pero eso de la heap lo odio.
Yo odio las multiplicaciones en matemáticas, no sé por qué deberían existir.

Kaxperday

Mmm

Citar
Por ejemplo, si Properties fuera un map<string,string>, donde la clave fuera el nombre del header:
-Cuando vayas a colocar el host, primeor lo buscas. Si noe xiste, 1 de 2: o pones el que tu programa genera, o tiras error.

La pregunta es: Si la función va a tirar error, ¿para qué le quieres pasar un valor "nulo"? En caso de que no tires error por ello, ¿para qué comprobar? Utilizas los datos que existan, y no utilizas los datos que no existan.

La función no tiene porqué tirar error, no confundas con el otro tema, el hilo son 2 preguntas distintas, la primera pasar una CLASE vacia a una funcion y trabajar con ella, y la otra devolver una clase nula en caso de error en una función que devuelva una clase.

Resuelta la segunda pregunta que creo que la haré con punteros o con Clases como referencia (ya veré).

Respecto a la primera acertastes Properties es en este caso un vector de tuplas de 2 string cada uno (y si quizás debería haber usado un map (seguramente lo cambie hehehe)), pero puede ser cualquier clase nula que se envie como parametro (porque en ese caso no queremos usarla), pero en la funcion se usa, si esa funcion es nula saltamos ciertas cosas que se hacen en mi caso y se cambian variables pasadas por referencia, entonces es necesario saber antes de que eso ocurra que es nula, y en este caso la función no tiene métodos para ello como muchas otras, entonces que es recomendable para saer si es nula sin tener que ponerse a trabajar con la función... era la pregunta XD quizás lo habéis entendido quizás no XDD pero difícil creo que lo tenéis.

En fin, lo que dices ivancea es lo mejor (que al acceder a un metodo en plan get() si no lo tiene CONTINUA (no da error y sale ya que se ha llamado intencionadamente con ese parametro a nulo por algo), lo malo que depende del contexto que eso sea siempre así, y puede ser más conveniente a veces pasar un puntero y comprobar directamente a null, que sería la opción más favorable para esos casos en mi opinión.

Bueno espero que se haya entendido, principalmente quería responder la segunda pregunta y sugerís las alternativas que presenté así que no ando mal encaminado.

PD: He llegado a la conclusión que me aburría mucho el día que abrí este hilo (ayer) XD, me apetecería charlar de programación jajaja.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.