Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - eferion

#601
Código (cpp) [Seleccionar]

Tarjeta::Tarjeta (const Numero& numero, const Usuario &user, const Fecha& caducidad) : numero_(numero), user_(&user), caducidad_(caducidad) {
  Fecha f_actual;
  titular_ = user.nombre() + " " + user.apellidos();

  if (caducidad_ < f_actual)
    throw(Tarjeta::Caducada(caducidad_));
  //(&user).es_titular_de(*this);
}


es decir, user tiene el modificador const.

La llamada es_titular_de tiene la firma:

Código (cpp) [Seleccionar]
void es_titular_de(Tarjeta&)

Es decir, no tiene el modificador const.

Cuando tu declaras una instancia como const quiere decir que, desde ese momento, no se puede modificar su estado. Esto implica que no se permiten las llamadas a métodos no const para dicha instancia.

Hasta ahí tu error. Luego hay varias cosas que no entiendo:

1. es_titular_de no tiene sentido que retorne void, es como preguntar a alguien la hora por la calle, que el otro la vea y no te responda... si lo que hace la implementación es imprimir por pantalla el resultado, mi consejo es que lo saques fuera de la clase.

Las razones son sencillas:

* La clase que contiene la función se llama Usuario, luego se presupone que su misión es gestionar la información de un usuario y no encargarse además de imprimir sus datos por pantalla, guardar los datos en un fichero y llamar a su novia en los aniversarios... responsabilidades definidas.

* Concentrar múltiples responsabilidades conlleva concentrar el código, lo que dificulta las tareas de depuración.

* El código se oscurece porque las estructuras de datos tienen a diluirse.

Tiene más sentido que la función luzca tal que

Código (cpp) [Seleccionar]
bool es_titular_de( const Tarjeta& ) const;

2. Tiene sentido crear instancias de "Caducada" con el constructor por defecto??

Entiendo que no, pero sin embargo, al no definir el constructor por defecto en la sección "private" se crea un constructor por defecto. Con poner solo la declaración en el archivo de cabecera vale. En C++11 también puedes impedir el uso del constructor por defecto de la siguiente forma:

Código (cpp) [Seleccionar]

class Caducada
{
  public:
    Caducada( ) = delete;
};


Lo mismo es aplicable a las clases Tarjeta y Usuario.

3. Esta línea

Código (cpp) [Seleccionar]
const Usuario * const user_; //Puntero constante al usuario dueño

te puede dar más problemas que alegrías. Sobretodo porque...

Código (cpp) [Seleccionar]
const Usuario* titular() const { return user_; }

Es decir, no hay ningún problema en que se modifiquen los datos del usuario.

Personalmente, dado que no hace falta que la clase cree el puntero, casi es más limpio pasar y almacenar una referencia, así evitas la "tentación" de poner un delete en un momento dado. Además, pasar clases por referencia te asegura de que la clase existe, ya que no se puede pasar un puntero a null por referencia.

Código (cpp) [Seleccionar]

class Tarjeta
{
  public:

    Tarjeta (const Numero& numero, const Usuario& usuario, const Fecha& fecha )
      : user_( usuario )
    { }

    Usuario& titular() const
    { return user_; }

private:

  Usuario& user_;
};



4.

Código (cpp) [Seleccionar]
throw(Tarjeta::Caducada(caducidad_));

No es buena idea lanzar una excepción que no herede de std::exception. El motivo es que, si no heredan de std::exception, la captura por defecto es catch( ... ) y en este caso pierdes toda la información acerca de la excepción. Además, siempre es recomendable que la excepción incluya un texto descriptivo... es útil en sistemas más complejos para seguir la traza del fallo.

5.

Código (cpp) [Seleccionar]
titular_ = user.nombre() + " " + user.apellidos();

Este campo autocalculado no tiene demasiado sentido... nombre() y apellidos() no son llamadas a operaciones costosas, es mejor autocalcular el valor cuando sea necesario, como los puntos anteriores, no es un fallo, solo una cuestión de diseño.

6. Las clases se crean sólo si hay razón para ello

Código (cpp) [Seleccionar]
class Id_duplicado {
  public:
    Id_duplicado (const Cadena& id) : id_duplicado(id) {}
    const Cadena idd() { return id_duplicado; }
  private:
    const Cadena id_duplicado;
  };


Vista así, esta clase no aporta nada, parece totalmente prescindible. Bien es cierto que lo ideal es tener el código bien repartido en muchas clases, cada una con una única responsabilidad, y con el menor código posible... pero claro, estas clases tienen que tener una razón de ser y esta, vista así, no lo tiene. Llenar el código de clases inútiles te va a dificultar el mantenimiento de tu código y te va a dar problemas en el futuro... estás avisado.
#602
tienes que acostumbrarte a mirar un poco por la web... este tipo de preguntas se suelen resolver mirando la documentación sobre el uso de la función y sus parámetros:









FormatoSignificadoEjemplo
%fDecimal floating point, lowercase392.65
%FDecimal floating point, uppercase392.65
%eScientific notation (mantissa/exponent), lowercase3.9265e+2
%EScientific notation (mantissa/exponent), uppercase3.9265E+2
%gUse the shortest representation: %e or %f392.65
%GUse the shortest representation: %E or %F392.65

Fuente: http://www.cplusplus.com/reference/cstdio/printf/
#603
Bienvenido al foro.

Primera lección: El código etiquétalo con las etiquetas GeSHi correspondientes... así aparecerá coloreado y con un formato más legible.

rfib(fib++,x++,last);

Eso son postincrementos... es decir, es equivalente a:


rfib( fib, x, last );
fib++;
x++;


Vamos que estás haciendo la misma llamada todo el tiempo.

Además, en tu ejemplo pasas:

rfib(s,0,s);

Es decir, fib == last, luego...

if( fib+1 != last )

va a ser siempre cierto... más bien debería ser

if ( fib != last )

PD.: parto de la base de que *s está debidamente inicializado.
Un saludo.
#604
Cita de: eduardo17445 en  2 Abril 2014, 04:22 AM
este fue el codigo que hice para mostrar y ingresar ...

Lo siento, pero como te han dicho llevas 109 mensajes en este foro, ya deberías conocer las normas. Hasta que no utilices las etiquetas para el código me niego a responderte a cualquier duda.

Estaría bien que me secundase más gente... en cualquier caso yo ya he expresado mi  postura.
#605
Cita de: engel lex en  2 Abril 2014, 03:40 AM
pensé que la asiganción devolvería true siempre... pero ahora que lo pienso, si fuera así

Código (cpp) [Seleccionar]
a=b=2 a = true y b = 2 XD

D: sorry por la confusión, gracias por aclarar :P

El operador de igualdad se propaga... tu código es equivalente a:

Código (cpp) [Seleccionar]
b = 2; a = b;

Para más detalles, la declaración de un operador de asignación (recordemos que es sobrecargable ):

Código (cpp) [Seleccionar]
int operator=( int original );

Es decir, recibe un int y devuelve un int, luego si tenemos:

Código (cpp) [Seleccionar]
int a=b=c=d=e=f=20;

Todas esas variables van a valer 20.
#606
"digitos" puede tener tamaño 11 perfectamente, con eso podrá almacenar una cadena de 10 caracteres.

Si quieres que el buffer sea capaz de almacenar una cadena de longitud X has de declararlo, al menos, de tamaño X+1, ya que debes reservar un espacio para el carácter nulo.

Esto solo es aplicable a cadenas de caracteres.
#607
Programación C/C++ / Re: bucle con char
1 Abril 2014, 20:31 PM
un while se ejecuta hasta que la condición devuelva false o, en su defecto 0. Es decir, no está limitada a enteros.

Tu tienes que hacer una comparación dentro del while para que el bucle se repita hasta que la palabra elegida coincida con "fin". Dado que usas la clase string es tan sencillo como echar mano a los operadores, en concreto el operador != que, curiosamente, retorna un booleano.

El resto te lo dejo a ti, que es como se aprende.

Un saludo.
#608

char digitos[12], cualDescartar[2];

// ...

do
{
   longitud=2;
   // ...
   ok = verifica(cualDescartar, ok, longitud, i);
}while(ok);

// ...

if((p=strchr(ingreso, '\n'))){
 *p='\0';
}
else{
 ingreso[longitud] = '\0'; // <=========== AQUI!!!!!!
 while((ch = getchar()) !='\n' && ch!=EOF);
}


por pasos:

* "cualDescartar" tiene longitud 2 ( posiciones 0 y 1 )
* "longitud" se incializa a valor 2 ( mal vamos )
* ingreso[ longitud ] = '\0' ( toma castaña, escribimos fuera del array ).

El caso es que el compilador está poniendo en la pila primero a "cualDescartar" y despues "digitos", al salirte de "cualDescartar" escribes en "digitos"


Vaya, leosansan hemos puesto la respuesta a la vez XDDDD
#609
estás haciendo una petición POST al servidor... yo probaría primero con una petición GET, que son más sencillas.

GET y POST son las formas de enviar información al servidor. Los parámetros que se pasan por GET van concatenados a la url, mientras que los que se envían por POST van en segundo plano. Es posible que tu problema sea que el servidor se quede esperando a que le lleguen los datos por POST y por eso no te responde correctamente.
#610
Cita de: vangodp en 31 Marzo 2014, 20:44 PM
En la linea 42 del ultimo ejercicio:
  Base* base2 = new Base( *derivada );
Seria esto:
Base * base2 = new Base ( *base );
¿no?
por que "derivada" no esta declarada y Derivada no sera :D

Cierto, cosas del copypaste... escribí todo sobre la marcha, desde el movil no se puede hacer mucho mas.

Cita de: vangodp en 31 Marzo 2014, 20:44 PM
Eres una enciclopedia ambulante =D

Muchas gracias por el cumplido, pero siendo sincero, aquí hay gente tanto o más buena que yo. Ayudo en lo que puedo.

Cita de: vangodp en 31 Marzo 2014, 20:44 PM
No tengo ni idea sobre esto... jeje

Es una sobrecarga del operador de asignación. Por defecto C++ asigna un operador de asignación por defecto, pero te ofrece la posibilidad de sobrecargarlo para adaptarlo a tus necesidades... por ejemplo por si manejas memoria dinámica, no copiar los punteros en sí sino también su contenido (para que cada copia tenga su propia memoria). De la misma forma se pueden sobrecargar el resto de operadores, incluso para los usos más variopintos e insospechados.

Cita de: vangodp en 31 Marzo 2014, 20:44 PM
Aprender C++por cuenta cuesta mucho -_-'

Yo lo dejaría en "Aprender C++ cuesta mucho". C++ es un lenguaje muy abierto con infinitas posibilidades y formas de hacer las cosas y eso hace que cueste muchísimo sentir que lo dominas en su mayoría ( completamente ya te digo que es una tarea compleja, tiene partes, como los templates... hay gente que hace maravillas con eso aunque yo no soy partidario de escribir código tan enrevesado. ). Pero bueno, al final te haces con el timón y eso te hace sentir orgulloso de ti mismo XD

Y poco más, si te aparecen más dudas tu pregunta, que para eso estamos.