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

 

 


Tema destacado: Estamos en la red social de Mastodon


  Mostrar Mensajes
Páginas: 1 2 3 4 5 [6] 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ... 45
51  Programación / Programación C/C++ / [C++11] (Consulta) El compilador me pide que ponga la palabra typename en: 19 Febrero 2017, 17:39 pm
Hola, muy buenas. Estoy haciendo una clase 'Vector' en C++ (tamaño dinámico, pero se asigna una sola vez). El caso es que uno de los constructores acepta una initializer_list, donde puedes poner todos los componentes del vector. Este es el código:

Código
  1. template<typename TipoComponente>
  2. class Vector {
  3.   [...]
  4.   public:
  5.      [...]
  6.      Vector(const std::initializer_list<TipoComponente> &componentes)
  7.         : Vector(componentes.size())
  8.      {
  9.         typename std::initializer_list<TipoComponente>::const_iterator iterador = componentes.begin();
  10.         int i = 0;
  11.  
  12.         while(iterador != componentes.end()) {
  13.            vector[i] = *iterador;
  14.            i++;
  15.            iterador++;
  16.         }
  17.      }
  18.      [...]
  19. };

LA pregunta es: ¿por qué el compilador me obliga a poner la palabra 'typename' antes de la declaración del iterador? Este es el error que sale si no la pongo:

Código:
||=== Build: Debug in Reversi (compiler: GNU GCC Compiler (x86_64)) ===|
..\Reversi\reversi\herramientas\vector.hpp||In constructor 'Vector<TipoComponente>::Vector(const std::initializer_list<_Tp>&)':|
..\Reversi\reversi\herramientas\vector.hpp|22|error: need 'typename' before 'std::initializer_list<_Tp>::const_iterator' because 'std::initializer_list<_Tp>' is a dependent scope|
..\Reversi\reversi\herramientas\vector.hpp|22|error: expected ';' before 'iterador'|
..\Reversi\reversi\herramientas\vector.hpp|25|error: 'iterador' was not declared in this scope|
..\Reversi\reversi\herramientas\vector.hpp||In instantiation of 'Vector<TipoComponente>::Vector(const std::initializer_list<_Tp>&) [with TipoComponente = float]':|
C:\Users\Carlos\Desktop\Programacion\Proyectos\Reversi\main.cpp|43|required from here|
..\Reversi\reversi\herramientas\vector.hpp|22|error: dependent-name 'std::initializer_list<_Tp>::const_iterator' is parsed as a non-type, but instantiation yields a type|
..\Reversi\reversi\herramientas\vector.hpp|22|note: say 'typename std::initializer_list<_Tp>::const_iterator' if a type is meant|
||=== Build failed: 4 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|

No me entero muy bien de lo que me queire decir el compilador. Espero que me puedan ayudar. Muchas gracias!
52  Programación / Programación C/C++ / Re: Constructores C++ en: 14 Febrero 2017, 15:24 pm
Si, pero new retorna puntero a obtejo, y ahi no se estan declarando punteros
53  Programación / Programación C/C++ / Re: pregunta sobre cabeceras c++ y un poco de windows en: 14 Febrero 2017, 09:05 am
Cuando usas un define básico, lo que hace el compilador, antes de compilar propiamente, preprocesa el código. En el caso de los define, el preprocesador lo que hace es sustituir literalmente lo que hayas puesto como primera palabra con todo lo que le sigue.

Ejemplo:

Código
  1. #define UN_DEFINE variable
  2.  
  3. int main() {
  4.   int UN_DEFINE;
  5.  
  6.   UN_DEFINE = 10;
  7.  
  8.   return 0;
  9. }

Al preprocesar el código, quedaría así:

Código
  1. int main() {
  2.   int variable;
  3.  
  4.   variable = 10;
  5.  
  6.   return 0;
  7. }

Esos son los 'define' más básicos, se pueden elaborar más (por ejemplo, con parámetros)
54  Programación / Programación C/C++ / Re: Constructores C++ en: 14 Febrero 2017, 08:59 am
Hola estas declarando mal, trata con esto

Código
  1. Persona miPersona = new Persona("Alex");
  2. Persona otraPersona = new Persona("Sergio");
  3.  

Eso es en Java.

Código
  1. cout<<Mipersona.GetNombre();

El método es Getnombre, sin mayúscula en la N
55  Programación / Programación C/C++ / Re: Porque no puedo pasarle la direccion de la cadena? strtol en: 12 Febrero 2017, 02:41 am
Sabiendo que esto era el error,

Código
  1. char prueba[20];
  2. ret = strtol(str, &prueba, 10);
  3. printf("\nProbando: %c%s%c\n",34,prueba,34);

Está todo bien.

______________________________________________

Si quieres más información de strtol, te aconsejo visitar el siguiente link:

http://www.cplusplus.com/reference/cstdlib/strtol/
56  Programación / Programación C/C++ / Re: Porque no puedo pasarle la direccion de la cadena? strtol en: 12 Febrero 2017, 00:16 am
Lo que decía hace esto:

1º Se salta todos los espacios que haya en la cadena que le pasas.
2º Te lee y convierte los digitos del numero hasta que se encuentre uno que no sea dígito o cuando llegas al final de la cadena.
3º Te devuelve, además del número, la dirección del primer elemento que se ha encontrado que no es dígito.

Código de ejemplo:

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. int main() {
  5.   char numero_str[] = "124lo que sea";
  6.   int numero;
  7.   char *siguiente;
  8.  
  9.   numero = strtol(numero_str, &siguiente, 10);
  10.  
  11.   fprintf(stdout, "El numero convertido: %i\n", numero);
  12.   fprintf(stdout, "Desplazamiento de \"siguiente\" respecto \"numero_str\": %i\n", (int)siguiente - (int)numero_str);
  13.   fprintf(stdout, "Bytes apuntados por \"siguiente\": '%s'", siguiente);
  14.  
  15.   return 0;
  16. }

Salida:

Código:
El numero convertido: 124
Desplazamiento de "siguiente" respecto "numero_str": 3
Bytes apuntados por "siguiente": 'lo que sea'

Como ves, strtol te ha convertido bien el número.

Lo que decía es que strtol lee dígitos hasta que se encuentre uno que no lo sea. En nuestro ejemplo ("124lo que sea"), strtol lee carácter a carácter. '1' es dígito, convierte y continúa. '2' es dígito, convierte y continúa. '4' es dígito, convierte y continúa. 'l' no es dígito, por lo que para ahí, y devuelve la dirección (que pertenece al arreglo) del elemento 'l'. Como se puede ver en el segundo fprintf, este elemento es el 3.

Nota un poco más técnica: te puedes fijar en el detalle de que la dirección de "siguiente" menos la del arreglo es 3, lo que quiere decir que "siguiente" apunta a 3 bytes más allá del arreglo, y como el arreglo tiene 14 elementos, eso significa que "siguiente" apunta a un elemento del arreglo. Esto deja claro que no se usa memoria dinámica.
57  Programación / Programación C/C++ / Re: Porque no puedo pasarle la direccion de la cadena? strtol en: 11 Febrero 2017, 23:16 pm
Hola gracias por responder, pero con strtol no estoy modificando la direccion del puntero simplemente llenandolo. poniendo caracteres dentro

No, una de las cosas que hace strtol es guardarte en la dirección que le pasas la dirección del primer elemento después del número.

"los arreglos se puede decir que son punteros disfrazados"

Eso se dice para facilitar la comprensión de sintaxis de los arreglos, pero la realidad es la que dije. Un arreglo NO es lo mismo que un puntero. Lo único similar entre ellos es su sintaxis.
58  Programación / Programación C/C++ / Re: Porque no puedo pasarle la direccion de la cadena? strtol en: 11 Febrero 2017, 22:57 pm
Lo que no puedes hacer es pasarle la dirección de un arreglo. Conceptualmente no puedes porque no puedes modificar la dirección de un arreglo.

Nota por si quieres sumar conocimientos (conocimientos obtenidos experimentalmente con el compilador MinGW y MinGW-w64): físicamente no puedes porque un arreglo no guarda una dirección de memoria. En realidad, un arreglo no se almacena en memoria. Al referirte a un elemento del arreglo, el compilador sabe la dirección virtual del primer elemento del arreglo, y por tanto sabe la del elemento. Cuando intentas acceder a la dirección de un arreglo, la dirección que obtienes es la misma dirección del primer elemento del arreglo. Código que lo demuestra:

Código
  1. #include <stdio.h>
  2.  
  3. int main() {
  4.   char arreglo[64];
  5.  
  6.   fprintf(stdout, "El arreglo apunta a:        %p\n", arreglo);
  7.   fprintf(stdout, "El arreglo tiene direccion: %p\n", &arreglo);
  8.  
  9.   return 0;
  10. }

Resultado en pantalla:

Código:
El arreglo apunta a:        000000000023FE10
El arreglo tiene direccion: 000000000023FE10

Espero que se haya entendido
59  Programación / Programación C/C++ / Re: [C++][Consulta] Error inesperado con destructor en: 3 Febrero 2017, 18:19 pm
Sii con el gdb (y mucho esfuerzo, por fin me entere del problema. Con C++ hay que tener un cuidado especial, tanto o mas que con C xD (supongo que sera cuestion de muucha practica, como siempre)

Muchas gracias por sus respuestas!!
60  Programación / Programación C/C++ / Re: [C++][Consulta] Error inesperado con destructor en: 3 Febrero 2017, 08:51 am
No entiendo muy bien eso de duplico. A ver, tengo el método Eliminar, que te elimina una rama del árbol. Este no comprueba que el árbol que le pases sea nulo (es una precondición que no será así, por así decirlo). Una vez que tengo ese método, creo otros dos que te eliminan la rama izquierda y la rama derecha, las cuales comprueban si la rama es válida (si esta no es nula). Una vez que tengo dos métodos que te eliminan dos ramas (sé que se podría haber resumido en una, pero me pareció útil para mis propósitos) tener métodos que te eliminen ramas independientes. El caso es que el constructor elimina el árbol formado por la rama izquierda y elimina el formado por la de la derecha:

Destructor:
    Elimina rama izquierda.
    Elimina rama derecha

No entiendo dónde está el conflicto.

________________________________________________________

He probado, desde el main, hacer lo del constructor, lo he eliminado y así si que funciona.

Nuevo main:

Código
  1. int main() {
  2.   ArbolBinario<int> arbol;
  3.  
  4.   arbol.SetDato(7, "");
  5.   arbol.ReemplazarRamaIzda(20, "");
  6.   arbol.ReemplazarRamaIzda(5, "0");
  7.   arbol.ReemplazarRamaDcha(7, "00");
  8.   arbol.ReemplazarRamaDcha(4, "0");
  9.   arbol.ReemplazarRamaIzda(1, "01");
  10.   arbol.ReemplazarRamaDcha(2, "01");
  11.   arbol.ReemplazarRamaDcha(8, "");
  12.   arbol.ReemplazarRamaIzda(10, "1");
  13.  
  14.   cout << arbol.ToString();
  15.  
  16.   arbol.EliminarRamaIzda();
  17.   arbol.EliminarRamaDcha();
  18.  
  19.   return 0;
  20. }

Por lo que alguna condición/requisito especial tiene que tener el destructor.

_____________________________________________________________


He probado a poner cout << "Algo" << endl en el destructor y esto sale:

Algo
Algo
Algo
Algo
Algo
Algo
Algo
Algo
Algo

¿Por qué se llama tantas veces?

______________________________________________________________


Soy nuevo en C++ (vengo de C), ¿delete Objeto llama al destructor del objeto?
Páginas: 1 2 3 4 5 [6] 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ... 45
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines