elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


  Mostrar Mensajes
Páginas: 1 2 [3] 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... 24
21  Foros Generales / Dudas Generales / Re: Función de amigo en C ++ en: 4 Abril 2023, 18:04 pm
Nota: esto debería ir en el subforo de C++. Aquí difícilmente lo van a ver los foreros que programan en C++. Yo lo vi porque me salió la respuesta de arriba en "mensajes recientes".

No sé si aún lo necesites, pero si lo mueven al subforo correcto igual a alguien le sirve después. Antes que nada, el mensaje de arriba, que parece ser copy/paste de ChatGPT-3, es un completo disparate, así que mejor ignorarlo.

Primero, ¿estás seguro de que copiaste bien esto?

Código
  1. friend typename RealType<S>::type foo(C<S> &c);

porque ahí estás declarando como amiga una función normal (no plantilla), que además va a tener precedencia sobre las que declaraste (que son plantillas), así que te debería dar error de enlazado. Si dices que te funciona bien para C<double>, supongo que más bien la declaraste así:

Código
  1. friend typename RealType<S>::type foo<S>(C<S> &c);

que es la forma correcta. Y ahí sí tienes el problema que comentas, porque con estas declaraciones:

Código
  1. template <class S>
  2. typename RealType<S>::type foo(C<S> &c);
  3.  
  4. template <class S>
  5. typename RealType<std::complex<S> >::type foo(C<std::complex<S> > &c);

nota que el parámetro de tipo para la plantilla es S en las dos. En ningún caso es std::complex<S>. Lo que el compilador hará será sobrecargar la función foo<S>: una versión recibe un parámetro de tipo C<S>&, y la otra uno de tipo C<std::complex<S> >&. Esto responde a tu otra pregunta: no, no es especialización sino sobrecarga.

Por lo tanto, si tienes algo como esto:

Código
  1. C<double> c_real;
  2. C<std::complex<double> > c_complejo;
  3. foo(c_real);
  4. foo(c_complejo)

las funciones que se generan son (omito los tipos de retorno por legibilidad):

Código
  1. foo<double>(C<double>& c);
  2. foo<double>(C<std::complex<double> >& c);

nota que las dos "se llaman" foo<double>. Sin embargo, en la clase C:

Código
  1. template <class S>
  2. class C
  3. {
  4.  friend typename RealType<S>::type foo<S>(C<S> &c);
  5.  // ...
  6. };

si declaras una variable C<std::complex<double> >, entonces, en lo que respecta a C, S es igual a std::complex<double>. Por lo tanto, lo que se estaría declarando como amiga es una hipotética función:

Código
  1. foo<std::complex<double> >(C<std::complex<double> >& c);

pero como te dije, la función que declaraste se genera como:

Código
  1. foo<double>(C<std::complex<double> >& c);

que no es amiga de C, y de ahí el error. No sé exactamente qué quieras lograr, pero posiblemente esto sea lo que buscas:

Código
  1. template <class S>
  2. class C
  3. {
  4. friend typename RealType<S>::type foo<typename RealType<S>::type>(C<S>& c);
  5. };

Así, en ambos casos se declararía como amiga foo<double> (siquiendo con los ejemplos), en su versión sobrecargada de acuerdo al tipo de C.
22  Programación / Programación C/C++ / Re: Ejecutar métodos de un objeto en otros en: 3 Marzo 2023, 00:52 am
Las referencias siempre deben referirse (valga la redundancia) a algo, desde el momento de su creación, y por lo tanto se deben inicializar en su definición. Esto no es válido:

Código
  1. int& ref;

porque ¿a qué hace referencia ref? A nada. Está básicamente en el limbo, y eso no correcto. Esto sí:

Código
  1. int x;
  2. int& ref = x;

Y algo similar ocurre con las constantes. En el caso de los constructores, las variables miembro son creadas antes de que el constructor se ejecute. El constructor simplemente les asigna valores. Por eso esto no sería válido:

Código
  1. Persona::Persona (const Mapa& m)
  2. {
  3. /* Error: antes de haber llegado aqui (al cuerpo del constructor), ya se deberia
  4. haber creado la variable mapa, pero obviamente no hay nada a lo cual haga referencia
  5. (seria como en el ejemplo incorrecto que te puse al inicio de este mensaje) */
  6.  
  7. /* Esta linea no estaria inicializando map (como te dije, eso sucede antes de ejecutar
  8. el constructor) sino simplemente intentando cambiar su valor. */
  9. map = m;
  10. }

Para eso se deben usar las listas de inicializadores de miembros en los constructores:

Código
  1. Clase::Clase() : variable_miembro{valor_de_inicializacion}

Esto hace que "variable_miembro" se cree e inicialice con el valor indicado. Eso se ejecuta antes de llamar al constructor.

Nota, también se pueden usar paréntesis en lugar de llaves:

Código
  1. Persona::Persona (const Mapa& m) : map(m)

Aunque hay diferencia entre estas dos formas (paréntesis y llaves), de momento lo mejor es no complicarte y usar la que te guste más. No sé si ya estés leyendo algún manual de C++, pero si no, deberías conseguirte uno para aprender estos temas, ya que hay otras circunstancias en las que es recomendable (y a veces necesario) inicializar las variables de esta manera.

Por cierto, en mi anterior respuesta me limité a decirte cómo podías hacer lo que preguntabas en tu último mensaje, pero no necesariamente pienso que alguna de las dos formas que mencionaste (tener una referencia como miembro o pasarla a las funciones que la necesiten) sea la más correcta. Por lo que veo, aún tienes un nivel básico, por lo que, si de verdad necesitas que los personajes accedan al mapa, probablemente sea mejor la segunda opción: simplemente pasar referencias const a las funciones. Tener como variable miembro una referencia viene con ciertas complicaciones que sería mejor evitar mientras no tengas más experiencia.
23  Programación / Programación C/C++ / Re: Ejecutar métodos de un objeto en otros en: 2 Marzo 2023, 20:51 pm
Te respondo sobre lo de pasar datos como de sólo lectura, porque la forma en que funcionan las constantes en C++ es muy peculiar, y si encima lo combinas con punteros o referencias, las reglas son complejas y pueden ser confusas y muy específicas de este lenguaje.

En general, si quieres que una función no pueda modificar los parámetros que recibe, los declaras como const. Si se trata de datos "grandes" como estructuras u objetos, lo conveniente es que sean referencias o punteros const (aunque en general deberías preferir las referencias). Sin embargo, en C++ si quieres poder tener objetos constantes de alguna clase, entonces hay que declarar todas las funciones miembro de esa clase que no modifican sus variables miembro (por ejemplo, los getters) como const. Ejemplo:

Código
  1. class Mapa
  2. {
  3. ...
  4. public:
  5. int getX () const;
  6. int getY () const;
  7. ...
  8. };
  9.  
  10. int Mapa::getX () const
  11. {
  12. return x;
  13. }
  14. // etc.

Además, las variables miembro const y/o referencia (que no sean static), se deben inicializar en la lista de inicializadores del constructor:

Código
  1. class Persona
  2. {
  3. private:
  4. const Mapa& map;
  5. int x, y;
  6.  
  7. public:
  8. Persona (const Mapa &m) ;
  9. };
  10.  
  11. // Nota como se inicializa map
  12. Persona::Persona (const Mapa& m) : map{m}
  13. {
  14. x = 9;
  15. y = 18;
  16. }

Cita de: maurus
o quizás el pasarle la referencia al método que va a usarla y nada más?

También podrías hacer eso, pero que sea referencia const. En cualquier caso, no olvides declarar como const las funciones miembro de Mapa que no modifican sus datos.
24  Foros Generales / Foro Libre / Re: dudas sobre empresa argentina mercadolibre en: 22 Febrero 2023, 22:22 pm
Si son GPL, entonces sí tienes derecho a distribuirlos y venderlos (y ya que estamos, puedes cobrar básicamente lo que quieras. Hay quien cree que sólo puedes cobrar el costo de la copia o soporte, pero eso es falso). La licencia impone ciertas obligaciones, como sabrás si la has leído, pero no necesitas el permiso de nadie para venderlos. Otra cosa es que Mercado Libre Venezuela pueda tener políticas propias que lo prohíban, y si es así, no hay mucho que puedas hacer, salvo buscar alguna otra plataforma.
25  Programación / Programación C/C++ / Re: Desde que pulse una tecla, que ejecuta dicha acción en: 12 Febrero 2023, 17:30 pm
No había visto que escribiste algo más.

El problema es que pones el _getch fuera del while. Lo que debes hacer es cambiar esto:

Código
  1. cin >> tecla;

por:
 
Código
  1. tecla = _getch();

La funcion _getch, lo que hace es leer el estado del teclado actual. Es decir, no ESPERA, sino que LEE, el estado actual.

No, no es así. La que hace eso es GetKeyboardState. _getch espera hasta que haya algo en su buffer (que es distinto del de stdin), y luego lo lee y devuelve el valor.
26  Programación / Programación C/C++ / Re: Como reemplazar una cadena c++ en: 9 Febrero 2023, 02:38 am
Falta información. ¿Eso compila siquiera, o te da algún error? ¿Qué tipo de dato es materias? Preferentemente deberías poner la declaración de toda la estructura Alumno.

Ya de entrada, con ese código no vas a poder modificar ninguna cadena, ya que ese iterador trabaja sobre copias. Necesitarías que fuera una referencia. De cualquier manera, si materias es un vector de cadenas, entonces it[ n ] sólo se refiere al caracter "n" de cada cadena en cuestión, por lo que no es válido asignarle una cadena ni compararlo con una. Pon la información que te digo y ya podríamos ver exactamente cuál es el error.
27  Programación / Programación C/C++ / Re: Desde que pulse una tecla, que ejecuta dicha acción en: 2 Febrero 2023, 21:56 pm
La forma más sencilla es usar _getch, declarada en conio.h. La aclaración pertinente (porque hay mucha información equivocada u obsoleta al respecto): aunque es sólo para Windows (lo cual claramente no es un problema en tu caso), actualmente es parte oficial de sus APIs, así que debería funcionarte con cualquier compilador para este SO sin necesidad de instalar nada extra.

También podrías implementar esta funcionalidad mediante SetConsoleMode, pero no le veo mucho caso, cuando _getch ya hace todo el trabajo sucio (internamente llama a SetConsoleMode y ReadConsoleInput).
28  Programación / Programación C/C++ / Re: Tengo un programa que no funciona como quiero en: 1 Febrero 2023, 16:55 pm
Es cierto que el problema se resuelve limpiando el buffer, pero fflush(stdin) no es lo correcto. Esta función sólo sirve para buffers de salida, no de entrada, como stdin. Usarlo con stdin funciona de casualidad en Windows, siempre que uses MinGW. Si usas, por ejemplo, alguna versión reciente de Visual C++, no funciona, y tampoco sirve en Linux, independientemente del compilador. Como se trata de un ejercicio simple y no estás validando entrada ni verificando errores, puedes limpiar el buffer con esta línea después del scanf:

Código
  1. while (getchar() != '\n');
29  Programación / Programación C/C++ / Re: cuando compilo sale virus en: 30 Enero 2023, 20:09 pm
Creo que conviene aclarar por si acaso. Aunque -Os y -s pueden reducir bastante el tamaño de los binarios, tienen sus desventajas. Compilar optimizando para reducir el tamaño puede reducir también el rendimiento (al menos en comparación con -O2 y -O3, que optimizan para velocidad de ejecución sin importar el tamaño), y en particular -s quita información que puede ser útil (aunque no indispensable en este caso para la ejecución del programa).

Aquí las puse porque podían servir para verificar que era un falso positivo y como un ejemplo de cómo las opciones de compilación influyen en el tamaño del ejecutable, pero en general sólo habría que usar ésas, y en especial -s, cuando hay una necesidad específica para hacerlo y se sabe lo que hace; de lo contrario no es muy recomendable.
30  Programación / Programación C/C++ / Re: cuando compilo sale virus en: 29 Enero 2023, 19:17 pm
Viendo el código, no hace nada raro, así que probablemente, como ya te dijeron, se trate de un falso positivo. La diferencia de tamaños no tiene nada de extraño, y depende del compilador usado, las opciones de compilación, etc. Por ejemplo, tan sólo con los análisis de VirusTotal, se puede ver que tú estás compilando para 64 bits, mientras que el .exe original fue compilado para 32 y con un compilador viejísimo (según el reporte, fue compilado en 2002...) así que no tiene el menor sentido comparar los tamaños.

Dicho lo anterior, si lo compilas, por ejemplo, con las opciones  -Os -s, debería reducir de forma importante el tamaño, y es posible que el falso positivo (si lo fuera) desaparezca.
Páginas: 1 2 [3] 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... 24
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines