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 - K-YreX

#721
Exacto, sobra el reservar memoria en el <main>. Imagina que cuando usas <new> compras un almacén para guardar "datos" y cuando ya no lo necesitas usas <delete> para venderlo. Un puntero guarda la dirección del almacén.

En tu caso la función <sumar()> compra un almacén, guarda la suma en él y te envía la dirección donde tienes tu almacén. Entonces en el <main> lo que haces es guardar la dirección que te envía la función <sumar()> en el puntero nuevo. No necesitas comprar otro almacén. Porque si compras otro almacén en el <main> y donde tienes guardada la dirección del nuevo almacén, guardas la dirección del almacén que compraste en la función <sumar()>, ya no sabes donde está el último almacén que has comprado. Y si no sabes donde lo tienes, no puedes venderlo... :-\

No sé si queda claro con esto pero es el mejor símil que se me ha ocurrido :-X
#722
Este es un error típico con la sobrecarga tanto del operador << como del operador >>.
Ambas sobrecargas son funciones, no métodos. Un método de una clase puede acceder a los miembros privados por si sólo porque en eso consiste un método, en una función que pertenece a una clase.

Sin embargo, esa sobrecarga es una función, no un método. Entonces el prototipo de la función debe definirse fuera de la clase. Y la implementación de la función si se hace en un fichero distinto se hace sin referenciar la clase a la que pertenece (ya que no pertenece a ninguna).

Y cuando queremos hacer que una función sea "friend" entonces el prototipo lo incluimos dentro de la clase precedido de la palabra <friend> pero si no se usa la palabra <friend> entonces hay que declararlo fuera de la clase.

Código (cpp) [Seleccionar]

class MiClase{
    private:
        // miembros y metodos privados
    public:
        // miembros y metodos publicos
        // Opcion 1: sobrecarga con friend
        friend std::ostream& operator<<(ostream&, const MiClase&);
};
// Opcion 2: sobrecarga sin friend
std::ostream& operator<<(ostream&, const MiClase&);


Espero haber resuelto tus dudas respecto a este tema. Suerte :-X

PD: He visto un extraño <ostring> en tu código... :silbar:
#723
Se eliminan ambos y ahora te explico.
Cuando se elimina un puntero, no eliminas el puntero como tal, sino que liberas la memoria a la que apunta el puntero. Cuando asignas un puntero a otro, ambos apuntan a la misma dirección de memoria. Entonces con eliminar uno de los dos, ya queda liberada la memoria.

Código (cpp) [Seleccionar]

int* sumar(int a, int b){
    int *suma = new int(a+b); // reservas memoria para un entero
    return suma;
}

int main(){
    int *psuma = sumar(2,2); // psuma apunta a la misma memoria que apuntaba suma
    delete psuma; // liberamos la memoria a la que apunta psuma que es la misma que suma
}
#724
Cita de: digimikeh en 10 Febrero 2019, 22:43 PM
Hola!
Me he topado con el siguiente escenario:
Código (cpp) [Seleccionar]

//En este fragmento al terminar la función, se destruye el contenido de suma y retorna null o vacío, y el puntero suma sigue existiendo en memoria....
int RetornaUnaSuma(int a, int b){
    int * suma = new int;
    *suma = a+b;
    return *suma;
}
//Aqui intento retornar un puntero creado dentro de la misma función...
int * RetornaUnaSuma(int a, int b){
    int * suma = new int;
    *suma = a+b;
    return suma;
    //pero al terminar la función, se destruye el contenido y retorna una dirección de memoria sin contenido, el puntero sigue existiendo..
}

Según yo es mala práctica declarar punteros que quieras retomar dentro de una función o un ámbito...  bueno aparte de mala practica no funciona el retorno...Es como lo pienso?...
Probablemente se pueda devolver punteros cuando éstos mismos ingresan como argumento...
La función sería:
Código (cpp) [Seleccionar]

//Segun yo esto debe funcionar...
int * RetornaUnaSuma(int * pSuma, int a, int b){
    *pSuma = a+b;
    return pSuma;
}

Que opinan...
Saludos.

Respecto al primer mensaje, te dejo tres variantes para analizar cada una de ellas.
  • Variante 1
    La más simple, una función que suma los parámetros en un entero y lo retorna.
    Código (cpp) [Seleccionar]

    int sumar(int a, int b){
        int suma = a + b;
        return suma;
    }

    En este caso no hay mucha complicación, la variable <suma> que es de ámbito local se destruye al terminar la función.

  • Variante 2
    Usando punteros. Creamos un puntero a entero donde se va a guardar la suma y retornamos el puntero .
    Código (cpp) [Seleccionar]

    int* sumar(int a, int b){
        int *psuma = new int (a + b);
        return psuma;
    }

    En este caso como estamos usando memoria dinámica al usar <new>, tenemos que liberar luego la memoria con <delete>. Como la función retorna el puntero no hay problema porque esa función se tiene que asignar a un puntero a entero en otro sitio (ya sea en el <main> o en otra función). Entonces liberamos la memoria en ese sitio:
    Código (cpp) [Seleccionar]

    int main(){
        int *psuma = sumar(2,2);
        // usas el puntero psuma
        delete psuma;
    }


  • Variante 3
    Esto es lo que has implementado en primer lugar y la opción más rara y menos apropiada. Crear un putero a entero donde guardar la suma y retornar el valor de la suma .
    Código (cpp) [Seleccionar]

    int sumar(int a, int b){
        int *psuma = new int (a + b);
        return *psuma;
    }

    En este caso tenemos un problema con la memoria dinámica. Una de las cosas que tiene la memoria dinámica es que cuando se crea un objeto/variable usando esta, el objeto/variable siempre debe estar apuntado por algún puntero. Si deja de ser apuntado por alguien, se pierde. Entonces aquí cuando acaba la función retorna el valor de la suma, el cual es correcto, pero se pierde el puntero <psuma> por lo que ya no se puede liberar.
    Código (cpp) [Seleccionar]

    int main(){
        int suma = sumar(2,2);
        // usamos la variable suma pero...
        // hemos perdido el puntero local de la funcion
    }



    Si quieres profundizar un poco el tema de los valores de retorno, que se guarde temporalmente el valor que se devuelve antes de ser destruido puedes indagar un poco dentro del lenguaje ensamblador. Puedes ver una llamada a función sencilla como esta para ver como la función guarda en un registro el valor de retorno. Entonces cuando la función ha acabado, el valor de retorno está guardado en un registro que debe ser guardado en otro sitio antes de volver a usar ese registro, por eso hay que asignarlo a una variable. Suerte :-X
#725
Programación C/C++ / Re: Acabo de empezar
10 Febrero 2019, 19:44 PM
Precisamente esa es la utilidad del foro. Compartir dudas o problemas que te surjan para recibir ayuda de otras personas. Aunque hay que diferenciar entre preguntar dudas o errores y pedir tareas. Cuando crees un tema que sea específico, ya que si copias el enunciado de un ejercicio y esperas que alguien te haga la tarea, no vas a conseguir respuestas...

Dicho esto, este subforo es de C/C++ por lo que este tema imagino que será movido o incluso eliminado.
(Te recomiendo leer las normas del foro, sobre todo por el tema de usar etiquetas para el código que se hace muy pesado ver trozos de código que no están entre etiquetas. Te dejo el enlace) Suerte :-X
#726
No. La palabra <ifstream> viene de <input> + <fstream> y la palabra <fstream> viene de <file> + <stream>.
Aunque coincida que la palabra empieza por <if>, ambas letras vienen de distintas referencias. :-X
#727
Es una clase para manejar los streams de entrada.
Normalmente cuando se trabaja con streams se incluye la librería <fstream>. Esta incluye tanto los streams de entrada <ifstream> (input stream) como los streams de salida <ofstream> (output stream). :-X
#728
Programación C/C++ / Re: problemac++
6 Febrero 2019, 00:16 AM
No se realizan tareas. Si quieres recibir ayuda muestra tu progreso con el programa y especifica una duda o error concreto de este. Sino nadie va a hacerte el programa... :-X
#729
CitarSe que tengo que insertar una nueva estructura en el main que va a ser la que mande a cima
No sé a qué te refieres con esto. Si puedes explicarte un poco... :-X
#730
Cuando te pide en el apartado b) crear 3 variables de ese tipo se refiere a crear 3 variables del tipo <Punto>. Lo puedes hacer como lo has hecho con un array o crear 3 variables independientes. Para trabajar con ellos en este caso es más sencillo como lo has hecho tú para poder manipularlo todo con un <for>.

Y las estructuras no es obligatorio declararlas así. Te muestro a continuación ambas formas de declarar instancias (objetos) de una estructura:
VARIABLES GLOBALES

struct Nombre{
    // miembros
} n1, n2, n_array[2];

int main(){
    // n1 n2 y n_array son objetos globales
}


VARIABLES LOCALES

struct Nombre{
    // miembros
};

int main(){
    Nombre n1, n2, n_array[2];
    // n1 n2 y n_array son objetos locales
}


Espero que esto te sirva. Si llegas a trabajar con C++ y con clases se puede hacer igual que aquí. Suerte :-X