Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Estas en el tema de ¿Para qué necesito un Constructor? (Sí, novato inside XD). en el foro de C/C++ en Foros del Web. Hola! Llevo unos meses aprendiendo a programar de manera autodidacta porque quiero empezar el año que viene algún módulo. Así que no seáis muy crueles ...

  #1 (permalink)  
Antiguo 14/04/2015, 16:53
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Pregunta ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola! Llevo unos meses aprendiendo a programar de manera autodidacta porque quiero empezar el año que viene algún módulo. Así que no seáis muy crueles si creéis que pregunto alguna cosa obvia de la que no me he dado cuenta :)

Antes de nada, decir que es mi primer mensaje, que me he leído las FAQs, y que si incumplo alguna norma pido disculpas.

Tambien decir que antes de preguntar, siempre suelo tratar de investigar mucho por mi cuenta, y cuando no encuentro solución, es cuando pregunto.

Y bueno, este es el caso:

Estoy aprendiendo structs, y ello ha hecho que me dé de lleno con los constructores. El tema es que en todos los sitios dicen que es necesario para inicializar las variables de una struct, y que si no, las variables contendrían basura...

Vale pero, si el constructor es para inicializar esas variables, ¿por qué he podido hacer perfectamente un programita con esta struct, sin usarlo para nada? Es que de hecho lo de los constructores lo he leído después de hacerlo...

Cita:
struct coche {

1.char modelo[7];
2.char marca[5];
3.int anio=0;
4.int precio;
5.char coment[100];
6.static int total;

};


He marcado en negrita esa variable int anio, porque a lo que voy es, ¿por qué puedo inicializar perfectamente esa variable sin usar constructor, de modo normal? ¿Cuál es la diferencia entre usar el constructor o no usarlo entonces?

Gracias!
  #2 (permalink)  
Antiguo 14/04/2015, 18:16
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Y tu libro, ¿dice algo más sobre los constructores?
  #3 (permalink)  
Antiguo 14/04/2015, 18:35
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola! Gracias por responder.

¿A qué te refieres? yo no tengo ningún libro concreto, sino que busco por Internet. Y me encuentro cosas como:


Cita:
Los constructores son funciones miembro especiales que sirven para inicializar un objeto de una determinada clase al mismo tiempo que se declara.
http://c.conclase.net/curso/?cap=029

Bien, pero es que parece que también puede hacerse eso sin el constructor...

O cosas como esta:

Cita:

Sabrás que no puedes asignar valores a las variables miembro dentro de una clase... Sean del tipo que sea.

Por ejemplo:

class MiClase{
public:
int mi-variable;
};

https://espanol.answers.yahoo.com/question/index?qid=20110807014231AATerGg


Bien... pero es que, como digo, parece que SI se puede... o al menos yo he inicializado esa variable dentro del cuerpo de la clase, y no he encontrado ninguna pega...

Y como no sé que está pasando, o qué hago mal, o qué no he entendido, de ahí viene mi duda.

Si en las horas que me he pasado leyendo sobre el tema, se me ha escapado algo o no lo he entendido, es perfectamente posible. Pero es lo que tiene estar aprendiendo.

PD. Por algún motivo no consigo insertar los enlaces de modo que se puedan clickear directamente, ni con el hipervínculo ni con nada. Mis disculpas.

Última edición por BramSt; 14/04/2015 a las 18:43
  #4 (permalink)  
Antiguo 14/04/2015, 18:58
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola, hay que saber algunas cosas primero: en una estructura agrupar tipos de variables y también funciones, estas funciones dentro de estructuras son llamados métodos, y las variables se les llama atributos. Las estructuras son el paso previo antes de formular una clase (lo único que le falta a un struct para ser clase es tener atributos privados).

Una vez el compilador crea las estructuras, hay que darles valores a sus miembros, y para ello se crearon los constructores que son métodos que tu no los llamas (amenos que crees objetos anónimos), se llaman automáticamente para inicializar a los atributos. Lo que tu haces (i=0) es luego de llamar al constructor, y realmente lo que haces es una asignación.

Por otro lado la como método especial los constructores te permiten inicializar con valores dados por el usuario, que de otra forma no se podría:

Código C++:
Ver original
  1. struct punto{
  2. int _x, _y;
  3. punto(int x, int y) : _x(x), _y(y) {}
  4. };
  5.  
  6. int main(){
  7. punto p(2, 3);
  8.  
  9. return 0;
  10. }

O poner valores por defecto, poner constructores de copia, o con funciones más complejas como tu quieras.

Finalmente cuando la estructura finaliza su alcance de ejecución (cuando se sale del {} más externo que lo contiene), el compilador debe llamar a su destructor, es decir se debe especificar como destruir esa estructura que tu formaste, esto lo verás útil en manejo de memoria dinámica es decir con punteros en el heap, pues si no se destruye puede causar fugas de memoria (que aunque no se use ese objeto sigue ocupando espacio en la ram).

Saludos
  #5 (permalink)  
Antiguo 14/04/2015, 19:09
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola dmorill, gracias por tu respuesta.

Entonces si yo hiciera:

Código C++:
Ver original
  1. struct punto{
  2. int _x=0;
  3. int _y=8;
  4.  
  5. };

Por ejemplo, ¿estoy llamando sin saberlo a un constructor que yo no veo?

Espero no haber dicho igual una estupidez muy gorda XD
  #6 (permalink)  
Antiguo 14/04/2015, 19:20
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola, prueba esto y nos cuentas que sale por pantalla. :D ojo que en el main no llamas al constructor.

Código C++:
Ver original
  1. struct punto{
  2.     int _x = 0;
  3.     int _y = 8;
  4.     punto();
  5. };
  6. punto::punto(){
  7.     cout << _x << " " << _y << " Llamando al constructor." << endl;
  8. }
  9. int main(){
  10.     punto p;
  11.     cout << p._x << " " << p._y << " mostrando couts" << endl;
  12.  
  13.     cin.sync();
  14.     cin.get();
  15.     return 0;
  16. }

No olvides que los constructores te permiten asignar valores cuando creas las estructuras, con datos que pongas cuando los llamas, como en el ejemplo que puse antes. Y también estructuras mucho más complejas.

saludos
  #7 (permalink)  
Antiguo 14/04/2015, 19:35
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
yo no tengo ningún libro concreto...
Yo creo que deberías comprar o conseguir un buen libro, o dos, no hay nada mejor para empezar.
Cita:
Los constructores son funciones miembro especiales que sirven para inicializar un objeto de una determinada clase al mismo tiempo que se declara.
Es así, fíjate que habla de "inicializar un objeto", que puede incluir más que la inicialización de sus miembros, como tomar recursos como memoria, archivos, sockets, y cosas que se necesiten para dar por creado el objeto.
En un constructor también puedes poner anio = anio_actual(); por ejemplo, cosa que no puedes hacer al declarar anio en el cuerpo de la clase.
Cita:
Sabrás que no puedes asignar valores a las variables miembro dentro de una clase... Sean del tipo que sea.
Eso no tiene sentido. Una de las razones por las que es necesario hacerse de un buen libro es evitar contaminarse con esas cosas; ¿o vas a creer también absolutamente todo lo que te digamos en un sitio de escasa reputación como este?

En la struct que has puesto, quitando esos números 1. 2. 3. ... que no sé cómo han llegado ahí, no parece que hubiera nada notable. Y
Código:
struct punto{
int _x=0; 
int _y=8;
};
está perfectamente bien. Lo único que podría señalarse es que el nombre de las variables no conviene que comiencen con _, porque ese estilo está por costumbre reservado para los nombres internos de las librerías, y para evitar cualquier posibilidad de interferencia, se suele evitar esa forma.
  #8 (permalink)  
Antiguo 14/04/2015, 19:37
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
...si yo hiciera:


struct punto{
int _x=0;
int _y=8;

};

Si... En c++ si no especificas los constructores se te crean los constructores por defecto. Ese que has puesto es el constructor de copia, y tiene sobrecarga del operador.

Mire ese vídeo: https://www.youtube.com/watch?v=411393yBQRw

Este es sobre el constructor de copia: http://www.minidosis.org/#/actividad...torDeCopia.vid

Esto es sobre la sobrecarga de operadores: http://www.minidosis.org/#/actividad...Sobrecarga.vid

Temario completo: http://www.minidosis.org/#/temas

Partes del temario relacionado con los constructores:

http://www.minidosis.org/#/temas/Cpp.Clases
http://www.minidosis.org/#/temas/Cpp.Operadores

Recomiendo que los veas todos, te sorprendería la cantidad de cosas que enseña este gran maestro. Que aun bien no es 'todo' lo que abarca C++ pero es una buena introducción.
http://www.minidosis.org/#/temas
  #9 (permalink)  
Antiguo 14/04/2015, 19:59
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola!

0 8 llamando al constructor.

0 8 mostrando couts.


Me temo que esto me va a costar mucho pillarlo, o igual hoy han sido demasiadas horas XD

Es que no sé qué es lo que tengo que ver, la verdad.

Por otra parte, es que si yo hago (quitando el constructor y lo referente a él):

Código C++:
Ver original
  1. struct punto{
  2.     int _x = 0;
  3.     int _y = 8;
  4.  
  5. };
  6.  
  7.  
  8. int main(){
  9.     punto p;
  10.     cout << p._x << " " << p._y << " mostrando couts" << endl;
  11.  
  12.     cin.sync();
  13.     cin.get();
  14.  
  15.     return 0;
  16. }

Me sale: 0 8 mostrando couts...

¿Qué pinta el constructor en todo esto? Si no lo necesito para inicializar los miembros de la estructura, que es para lo que se supone que sirve, ¿para qué lo quiero?


------------


@lareto

Los números salen de que no había descubierto lo del Highlight y numeré el código a mano XD

Sobre el libro, yo ahora es que realmente no estoy tanto aprendiendo C++ como sí la Lógica de programación. Para eso sí me agencié un buen libro. El tema es que por guía de un colega que ha sido profe de programación para ingenieros incluso, ahora me toca pasar por las estructuras (que no están en el libro), y claro, me estoy dando de morros con todo esto de constructores, sobrecargas... que es nuevo para mí.

Tened en cuenta que he visto muy por encima funciones, memorias dinámicas, clases, objetos... sí he trabajado algo más con las cosas básicas, como me va mandando el libro (bucles, decisiones, arrays, matrices...). Pero todo con calma.

-----
@vangodp

Pues muchas gracias por los links!

Yo es que como ahí no veo función ninguna siquiera, más que un struct con dos variables dentro, no sé donde leches anda ese contructor por defecto que se supone que yo he puesto... XD

Creo que me queda mucho en este bonito pero lioso camino hacia la abstracción... XD

Última edición por BramSt; 14/04/2015 a las 20:04
  #10 (permalink)  
Antiguo 14/04/2015, 20:10
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Me sale: 0 8 mostrando couts...

¿Qué pinta el constructor en todo esto?
Nada.
  #11 (permalink)  
Antiguo 14/04/2015, 21:29
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

A ver en tu caso nada. En C++ las estructuras son parecidas a las clases pero con todos sus miembros públicos. ¿Que quiere decir eso? pues que puedes hacer eso que haces. a = b;

Pero en las clases no lo puedes hacer si no especificas claramente que esos datos son públicos.

Creo que te puse cosas que se adelantan a lo que estas viendo. En tu caso ves estructuras, y las estructuras tienen sus atributos como públicos. O sea que no necesitas constructores. O lo que es lo mismo que te ha dicho lareto "Nada"... No tiene nada que ver. Pero como preguntabas por constructores por defecto te los puse.

Ahora te ilustro con ejemplos:

Este ejemplo es con constructores:
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. struct Datos{
  5.     int n = 10; //valor inicial
  6. };
  7.  
  8.  
  9. int main (){
  10.    
  11.     //Creo un objeto de la estructura
  12.     Datos d;
  13.    
  14.     //imprimo lol
  15.     cout << d.n << endl;
  16.    
  17.    
  18.     //hago mis cosillas
  19.     d.n = 200;
  20.    
  21.     //imprimo nuevamente...
  22.     cout << "ahora cambio el valor: " << d.n << endl; //facil... ya ta. ¿Nada nuevo no? nos vemos al seguiente
  23.  
  24.     cin.ignore();
  25.     return 0;
  26. }
Nada nuevo. No necesito constructores

Ahora veamos lo mismo pero con clases. Las clases y las estructuras se parecen
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class Datos{     //Solo cambio struct por class y tengo clases. Pero es privada
  5.     int n = 10;  //puedo dar valor inicial igualmente
  6. };
  7.  
  8. int main (){
  9.     //todas las lineas que intentan acceder a la clase marcan error. Puedes comprobar comentandolas todas. Es por que es privada la clase si no se especifica otra cosa.
  10.     Datos d;
  11.    
  12.     cout << d.n << endl;
  13.    
  14.     d.n = 200;          
  15.    
  16.     cout << "ahora cambio el valor: " << d.n << endl;
  17.  
  18.     cin.ignore();
  19.     return 0;
  20. }

El codigo anterior marca error ya que una clase si que da error si no le decimos que es publica.
Miere el seguiente código:
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class Datos{    
  5.     public:     //Al decir que es public tu clase ahora se parece a una estructura. No le veo diferencias... ¡Prueba!
  6.     int n = 10;
  7. };
  8.  
  9. int main (){
  10.    
  11.     Datos d;
  12.    
  13.     cout << d.n << endl;
  14.    
  15.     d.n = 200;          
  16.    
  17.     cout << "ahora cambio el valor: " << d.n << endl;
  18.  
  19.     cin.ignore();
  20.     return 0;
  21. }

En el ejemplo anterior al declarar los miembros como publicos, se asemeja a tu estructura. Eso demuestra que las estructuras en C++ se asemejan a las clases, pero con sus miembros públicos.

Ahora el ejemplo del por que usar constructores por defecto.

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class Datos{    
  5.     private:     // Ojo! Ahora digo que es privada. No funciona si intento acceder a los miembros.
  6.         int n = 10;
  7.    
  8.     public:      // su constructor si es publico
  9.         Datos( int otroN ){ n = otroN; }
  10.         int getN (){ return n; }   //n al estar como privado no le puedo acceder directamente, pero la funcion getN() nos va retornar el numero por nosotros.
  11. };
  12.  
  13. int main (){
  14.    
  15.     Datos a(100);
  16.     cout << "a.n: " << a.getN() << endl;  //getN devuelve la n de a aun que sea privada. Eso es asi por que puedo acceder a la parte privada desde la publica. Quizas sea muy avanzado para ti eso, no te preucupes por eso ahora ;)
  17.    
  18.     Datos b = a; //Eso es un constructor de copia. Aun que use como si de una simple variable se tratara es un constructor. b ahora vale lo mismo que a
  19.    
  20.     cout << "b.n: " << b.getN() << endl;
  21.    
  22.  
  23.     cin.ignore();
  24.     return 0;
  25. }

Para eso se usan los constructores.

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class Datos{    
  5.     public: //volvemos publica la clase
  6.         int n = 10;
  7. };
  8.  
  9. int main (){
  10.    
  11.     Datos a;
  12.     a.n = 100;
  13.     cout << "a.n: " << a.n << endl;
  14.    
  15.     //Esto equivale al ejemplo anterior: Datos b = a; O sea es un constructor de copia.
  16.     Datos b(a);
  17.    
  18.     cout << "b.n: " << b.n << endl;
  19.  
  20.     cin.ignore();
  21.     return 0;
  22. }

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. struct Datos{    
  5.     Datos ( int otroA, int otroB, int otroC, int otroD, int otroE ){
  6.         a = otroA; b = otroB; c = otroC; d = otroD; e = otroE;
  7.     }
  8.     void imprimir(){
  9.         cout << a << ", "<< b << ", "<< c << ", "<< d << ", "<< e << endl;  
  10.     }
  11.    
  12.     int a;
  13.     int b;
  14.     int c;
  15.     int d;
  16.     int e; // podiamos tener 100 datos XDD
  17. };
  18.  
  19. int main (){
  20.    
  21.     Datos a(100,200,300,400,500); //volvemos a ser una estructura. Pero podemos usar constructores.
  22.    
  23.     a.imprimir();
  24.    
  25.     cin.ignore();
  26.     return 0;
  27. }

Ahora creo que ya te debería quedar algo más claro lo de los constructores.
Aun que sean structs puedes usar constructores. ¿Que es mas fácil, datos.a = 100; datos.b = 200; datos.c = 300;? .... ¿O Datos datos(100, 200, 300, 400, 500)?

En una estructura como la tuya a lo mejor no te conviene usar nada de eso, ni falta te hace. Pero los constructores están para usarlos. Ahora que te vangan y te digan que no tienen nada a ver y que este foro es poco fiable... Algunos tenemos más exp que otros, pero nunca he salido de un foro de programación con dudas. No se por que algunos tienen tan poca fé en los compañeros >_<.

Última edición por vangodp; 14/04/2015 a las 21:34
  #12 (permalink)  
Antiguo 15/04/2015, 05:22
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola,

Cita:
Iniciado por BramSt Ver Mensaje
¿Qué pinta el constructor en todo esto? Si no lo necesito para inicializar los miembros de la estructura, que es para lo que se supone que sirve, ¿para qué lo quiero?
XD
La idea era que te des cuenta que si definimos nosotros un constructor, éste se llamará automáticamente en el momento que se crea la estructura o el objeto. Sin importar que asignes valores a los atributos. Qué pasa cuando tu no defines el constructor, pues tengo entendido que el compilador te crea uno automáticamente, por eso puedes crear una estructura o una clase sin ponerlo.

Para qué lo quieres? imagínate que quieres crear 3 puntos en 1,2 ; 9, 8 y 10 20, con un constructor como el que te puse en el ejemplo sólo tendrías que poner

Código C++:
Ver original
  1. punto p1(1,2), p2(9,8), p3(10,20)

Mientras que si tu lo asignas lo haces con un sólo valor. Claro tu me podrías decir que puedes poner esto:

Código C++:
Ver original
  1. punto p1,p2,p3;
  2. p1._x =1; p2._y =2
  3. p1._x =9; p2._y =8
  4. p1._x =10; p2._y =20

si se puede pero como te das cuenta es mucho más largo, y ya que siempre se llama a un constructor pues es preferible usarlo.

Ahora bien, mira este código:

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. struct punto{
  5.     int _x = 1;
  6.     int _y = 5;
  7.     punto(int x, int y);
  8. };
  9. punto::punto(int x, int y){
  10.     _x = x, _y = y;
  11. }
  12.  
  13.  
  14. int main(){
  15.     punto p;    //te saltará un erro aquí
  16.     cout << p._x << " " << p._y << " mostrando couts" << endl;
  17.  
  18.     cin.sync();
  19.     cin.get();
  20.     return 0;
  21. }
Cuando construyas "punto p"te saldrá un error pues tu has definido un constructor que requiere dos int, y al llamarlo sólo con p no se los estas suministrando, se podría pensar que si no se los doy pues que tomen el valor de 1, 5. Pero no el compilador te daría error pues el constructor que intenta llamar requiere parámetros.

Para arreglarlo podrías definir otro constructor que se el por defecto (teniendo dos constructores para tu estructura):
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. struct punto{
  5.     int _x = 1;
  6.     int _y = 5;
  7.     punto();
  8.     punto(int x, int y);
  9. };
  10. punto::punto(){
  11.     _x = 0; _y = 0;
  12. }
  13. punto::punto(int x, int y){
  14.     _x = x, _y = y;
  15. }
  16.  
  17.  
  18. int main(){
  19.     punto p;    //ya no hay error
  20.     punto p(10, 20), p1(50, 80); //y puedes crear puntos y inicializarlos así de fácil
  21.     cout << p._x << " " << p._y << " mostrando couts" << endl;
  22.  
  23.     cin.sync();
  24.     cin.get();
  25.     return 0;
  26. }

saludos
  #13 (permalink)  
Antiguo 15/04/2015, 05:27
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

@vangodp, muchas gracias así da gusto.

Entonces, a ver si voy pillando algo: los constructores sirven:

1- para acceder a miembros privados
2- incluso para acceder a datos públicos, por comodidad, según la situación, no?

Tengo que mirarme eso de los constructores de copia porque obviamente también se me escapa. Eso y la extraña sintaxis que tienen los constructores para mí a veces, que unas veces se definen fuera del cuerpo de la clase/ estrcutura y otras dentro... una locura XD


Voy a estudiarme tus ejemplos aún mejor y a hacer algún ejercicio, a ver qué voy sacando en claro (aunque respóndeme si mis apreciaciones son correctas).

Otra cosa que me descoloca un poco es, en tu último ejemplo:


Código C++:
Ver original
  1. struct Datos{    
  2.     Datos ( int otroA, int otroB, int otroC, int otroD, int otroE ){
  3.         a = otroA; b = otroB; c = otroC; d = otroD; e = otroE;
  4.     }
  5.     void imprimir(){
  6.         cout << a << ", "<< b << ", "<< c << ", "<< d << ", "<< e << endl;  
  7.     }
  8.    
  9.     int a;
  10.     int b;
  11.     int c;
  12.     int d;
  13.     int e; // podiamos tener 100 datos XDD
  14. };

¿Cómo es eso de que pareces declarar las variables después de asignarlas? ¿O es válido porque Datos igual es sólo un prototipo? (ese datos() es un constructor, ¿verdad?).

Otra cosita: al no devolver un valor los constructores, ¿no debería llevar el void delante?

Efectivamente igual un problema es que igual se da por hecho que sé cosas que aún no sé, por eso especifiqué lo que había estudiado ya y lo que no :)

Por ahora la ayuda en foros me está siendo inestimable.

PD: @dmorill ahora estudio también tu post, que tiene buena pinta :)

Última edición por BramSt; 15/04/2015 a las 05:36
  #14 (permalink)  
Antiguo 15/04/2015, 05:59
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

@dmorill bien, hasta ahora creo sacar en claro, según lo que dices, si yo no defino un constructor para mi estructura, el compilador de manera "escondida" haría algo parecido a punto p(), ¿cierto?

Por otro lado, en tu ejemplo, ¿por qué "punto p" daría error? Quiero decir, ¿no lo debería ver el compilador como una instanciación de la clase (o como se llame crear una variable de tipo "punto"), en vez de como una llamada al constructor?

De no existir el constructor, o si es que existe por efecto si yo no lo defino, creo que esa sintaxis funcionaría perfectamente...

Como ejemplo de lo que quiero decir, pillo uno que me pusisteis antes (observad los comentarios):


Código C++:
Ver original
  1. struct punto{
  2.     int _x = 0;
  3.     int _y = 8;
  4.  
  5. };
  6.  
  7.  
  8. punto::punto(){//¿esto es llamar al constructor por defecto?
  9.     cout << _x << " " << _y << " Llamando al constructor." << endl;
  10. }
  11. int main(){
  12.     punto p;// por qué esto si funciona? no debería ser punto p()?;
  13.     cout << p._x << " " << p._y << " mostrando couts" << endl;
  14.  
  15.     cin.sync();
  16.     cin.get();
  17.  
  18.     return 0;
  19. }


Y otra cosita, ¿en este ejemplo se usa el operador de ambito (::) .¿Por qué? ¿Por que se está accediendo directamente a un miembro de clase?

Gracias! Espero no preguntar burradas muy gordas XD

Igual es que lo que debería haber hecho es ver las estructuras sólo de manera superficial (o profunda, pero sin temas de constructores aún), y antes de meterme a rollos de constructores, aprender bien el tema de funciones, que de hecho era el siguiente en mi libro de Lógica después de matrices... ¿qué creéis?

Y perdonad si parezco demasiado efusivo o pregunto muchas cosas juntas, es que esto de la Programación me está gustando (y costando) mucho y quiero aprender me cueste lo que me cueste.

Última edición por BramSt; 15/04/2015 a las 06:06
  #15 (permalink)  
Antiguo 15/04/2015, 06:40
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola
Cita:
Iniciado por BramSt Ver Mensaje
@dmorill bien, hasta ahora creo sacar en claro, según lo que dices, si yo no defino un constructor para mi estructura, el compilador de manera "escondida" haría algo parecido a punto p(), ¿cierto?
Para estructuras estoy casi seguro que si pero por si acaso esa pregunta se la paso a un veterano como vangodp jeje. Pero en las clases si que si. Se crea uno por defecto aunque no lo hayas definido.

Cita:
Iniciado por BramSt Ver Mensaje
Por otro lado, en tu ejemplo, ¿por qué "punto p" daría error? Quiero decir, ¿no lo debería ver el compilador como una instanciación de la clase (o como se llame crear una variable de tipo "punto"), en vez de como una llamada al constructor?

De no existir el constructor, o si es que existe por efecto si yo no lo defino, creo que esa sintaxis funcionaría perfectamente...
Primero partamos del hecho que el constructor siempre esta allí aunque no lo definas (se crea uno por defecto sin parámetros), cuando tu lo defines, el programa dice "a menos mal que se definió un constructor, ahora voy a usar el que el usuario declaro así me libro de hacer uno" jeje. Por tanto en el ejemplo que te puse, definí un constructor que funciona si y solo si tiene dos parametros (int x, int y), cuando el compilador crea la estructura punto el intenta llamar a tu constructor y como no tiene parámetros explota xd.

Por supuesto, como el otro ejemplo resolviendo ese problema tu puedes tener muchos constructores (eso es como sobrecarga de constructores, no le prestes mucha atención al termino sobrecarga jeje eso viene luego).

Código C++:
Ver original
  1. struct punto{
  2.     int _x = 0;
  3.     int _y = 8;
  4.     punto();     // OJO te faltaba declararlo acá.
  5. };
  6.  
  7.  
  8. punto::punto(){//¿esto es llamar al constructor por defecto?
  9.     cout << _x << " " << _y << " Llamando al constructor." << endl;
  10. }
  11. int main(){
  12.     punto p;// por qué esto si funciona? no debería ser punto p()?;
  13.     cout << p._x << " " << p._y << " mostrando couts" << endl;
  14.  
  15.     cin.sync();
  16.     cin.get();
  17.  
  18.     return 0;
  19. }

Vamos por partes, "punto::punto(){//¿esto es llamar al constructor por defecto?", no esto es implementar (vamos definir) el constructor, que se llamará siempre que se crea una estructura.

"punto p;// por qué esto si funciona? no debería ser punto p()?;"

Para esto tengo que explicarte cuales son las caracteristicas especiales de los constructores, pues son funciones muy importantes y especiales para c++.
* Los constructores no devuelven nada, pero son los únicos que no se les pone void. supongo que para diferenciarlos y por que son los consentidos de c++ xd.
*Los constructores de deben llamar igual que su clase o bien que su estructura. Por eso se llama "punto();" uno por default o bien "punto(int x, int y)" uno con parámetros.
* En teoria no debern hacer otra cosa que no sea poner valores a los atributos (variables sean publicas o no) de las estructuras o clases.
* Son funciones que se llamaran siempre, al crear estructuras o objetos, tu no las llamas. Por eso si funciona "punto p" y no punto p().

Cita:
Iniciado por BramSt Ver Mensaje
Y otra cosita, ¿en este ejemplo se usa el operador de ambito (::) .¿Por qué? ¿Por que se está accediendo directamente a un miembro de clase?
Sip, exacto jeje, los constructores son funciones que pertenecen a una estructura o una clase, por tanto se declaran dentro de los mismos y para implementarlos (si se hace fuera) se necesita los dos :: mira este ejemplo, voy a definir el mismo constructor de las formas que conozco, (ojo los constructores que definiré todos hacen lo mismo y sólo debes poner uno de ellos, no los 3 porque te daría error pues ya los has definido antes):
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. struct punto{
  5.     int _x;
  6.     int _y;
  7.     punto(int x, int y);   
  8. //declarandolo aquí dentro de la estructura.
  9.     punto(int x, int y) { _x = x; _y = y; };   
  10. //declarandolo e implementandolo  inline, así se puede definr métodos cortos
  11.     punto(int x, int y) : _x(x), _y(y) {}  
  12. // declarandolo e implementadolo inline, pero éste método es especial para los constructores. En herencia veras que es útil ponerlos así.
  13. };
  14. //implementandolo aqui fuera de la estrucutra.
  15. punto::punto(int x, int y){    
  16.     _x = x;
  17.     _y = y;
  18. }
  19.  
  20.  
  21. int main(){
  22.     punto p(0, 0);
  23.     cout << p._x << " " << p._y << endl;
  24.  
  25.     cin.sync();
  26.     cin.get();
  27.     return 0;
  28. }

Y yo personalmente te recomiendo que sigas siendo curioso y que uses constructores en tus estructuras.


Saludos
  #16 (permalink)  
Antiguo 15/04/2015, 14:39
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 11 años, 9 meses
Puntos: 28
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Voy a explicartelo también, pero voy a partir de cero.

Un constructor no es más que una función para inicializar una estructura, antiguamente en C cuando tenías una estructura como esta:

Código C++:
Ver original
  1. struct Imagen
  2. {
  3.     int dimensiones;
  4.     int colores;
  5.    // más y más atributos...
  6. };

Estos atributos los inicializas después de crearlos:
Código C:
Ver original
  1. Imagen unNombre;
  2.  
  3. unNombre.dimensiones = 0;
  4. unNombres.colores = 256;
  5. //etc.. etc..

Alguien se le ocurrió meter toda la rutina de inicializar en una función, por lo que quedó:
Código C:
Ver original
  1. Imagen unNombre;
  2.  
  3. InicializarImagen(&unNombre);

Mucho más legible, y se empezó a usar en todas las librerías de forma masiva.

El problema que tiene eso, esque te olvides de llamar a la función. Y ahí es cuando se liaba parda.

C++ plantea una mejora a este sistema, estas funciones pasan a llamarse constructores y se ejecutan siempre al crear una clase.

De modo que ahora sería:
Código C++:
Ver original
  1. struct Imagen
  2. {
  3.     int dimensiones;
  4.     int colores;
  5.    // más y más atributos...
  6.  
  7.    Imagen()
  8.   {
  9.        dimensiones = 0;
  10.        colores = 256;
  11.        //etc...
  12.   }
  13. };

Código C:
Ver original
  1. Imagen unNombre;
Mucho más claro. Al crear un objeto siempre se inicializa sin que tengas que acordarte de llamar a x función, ya lo hace el compilador solito.

Como habrás notado, el constructor tiene siempre el mismo nombre que el objeto. Esa es la sintaxis que se ha escogido.
  #17 (permalink)  
Antiguo 15/04/2015, 17:12
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Pues te felicito a ti también, @dmorill, la cosa se va aclarando... Me hacía falta algo como tus Highlights que me explique clarito las cosas.

El tema ese de la forma heredada fue lo que me terminó de trastornar ayer XD

Sólo hay una cosa que no pillo, así por encima:


Cita:
Son funciones que se llamaran siempre, al crear estructuras o objetos, tu no las llamas. Por eso si funciona "punto p" y no punto p().
Esto entronca con lo explicado por @amchacon, a quien le doy las gracias también desde aquí por supuesto, y se lleva su correspondiente +1 cuando acabe el post.

A ver si me he enterado entonces...

Cuando yo hago esto:


Código C++:
Ver original
  1. struct punto{
  2.  
  3.     int a=8;
  4.     int b=10;
  5.  
  6.  
  7.  
  8.  
  9. };
  10.  
  11. int main(){
  12.     punto p;
  13.     cout << p.a << " " << p.b << " mostrando couts" << endl;
  14.  
  15.     cin.sync();
  16.     cin.get();
  17.  
  18.     return 0;
  19. }

Estoy usando, sin saberlo (sin saberlo yo al menos XD), un constructor por defecto que el compilador crea y llama de forma automática, ¿no es así?

Es que primero necesito saber para aclararme:

punto p es una declaración de una variable u objeto de tipo "punto" (como un "int a" de toda la vida, vaya), o es un constructor en sí mismo? Es que claro, con eso de los constructores de copia que se asignaban como variables me descoloco un poco...

Después, en caso de ser un constructor, ¿es por su especial naturaleza de constructor que, al ser un constructor por defecto, se le llame usando "punto p" y no "punto p()" como entiendo que se haría con cualquier función sin parámetros "normal"?

Después también me choca que para definir el constructor fuera de la estructura, haya que volver a "redeclarar" sus parámetros, de tenerlos... pero eso supongo que es que me tengo que estudiar bien las funciones.

Última edición por BramSt; 15/04/2015 a las 17:18
  #18 (permalink)  
Antiguo 15/04/2015, 17:40
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Iniciado por BramSt Ver Mensaje
Estoy usando, sin saberlo (sin saberlo yo al menos XD), un constructor por defecto que el compilador crea y llama de forma automática, ¿no es así?
Así es.

Cita:
Iniciado por BramSt Ver Mensaje
punto p es una declaración de una variable u objeto de tipo "punto" (como un "int a" de toda la vida, vaya), o es un constructor en sí mismo? Es que claro, con eso de los constructores de copia que se asignaban como variables me descoloco un poco...
Si, es una declaración de una estructura (si usas class sería de un objeto de la clase punto). Y al declararlo se llama al constructor automáticamente.

Cita:
Iniciado por BramSt Ver Mensaje
Después, en caso de ser un constructor, ¿es por su especial naturaleza de constructor que, al ser un constructor por defecto, se le llame usando "punto p" y no "punto p()" como entiendo que se haría con cualquier función sin parámetros "normal"?
jeje por lo anterior pues no. Pero si el constructor tiene parámetros los llamas directamente cuando declaras la estructura u objeto. ej: punto(4, 5), punto(0, 0);

Cita:
Iniciado por BramSt Ver Mensaje
Después también me choca que para definir el constructor fuera de la estructura, haya que volver a "redeclarar" sus parámetros, de tenerlos... pero eso supongo que es que me tengo que estudiar bien las funciones.
Si al principio me molestaba también jeje, pero recuerda que puedes definirlas dentro también (dos de las 3 formas son dentro, declarando e implementando al mismo tiempo, por cierto estas formas de llaman funciones inline).

Por otro lado amchacon dice:

Cita:
Iniciado por amchacon Ver Mensaje
El problema que tiene eso, esque te olvides de llamar a la función (en c). Y ahí es cuando se liaba parda.

C++ plantea una mejora a este sistema, estas funciones pasan a llamarse constructores y se ejecutan siempre al crear una clase.
saludos"
Es decir que en c se tenían que llamar y en c++ lo hace automático el compilador. Así que no hay contradicción :D

Saludos

Última edición por dmorill; 15/04/2015 a las 17:53
  #19 (permalink)  
Antiguo 15/04/2015, 19:55
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Es decir que en c se tenían que llamar y en c++ lo hace automático el compilador. Así que no hay contradicción :D
En C no existe los constructores. Pero nada impide que uses una función de toda la vida que te "construya" el objeto.

En C++ no necesitan llamar por que cuando creas el objeto ya lo haces a la hora de crearlo. Si no lo haces o lo haces mal, no se crea. XD

Y preste mucha atención a el tema que comenta dmorill sobre el tema de los inline. Cuando declaras y defines todo dentro de una clase/estructura haces que la función sea una función inline.
¿Que es eso de las funciones inline?
Cuando creas una función no inline, esa se encuentra en una parte de la memoria. Cuando haces la llamada en una determinada linea dentro de main, esta detiene el programa en esta misma linea, se desviá hacia donde esta la función, y la ejecuta, acto seguido vuelve a donde se paro. Eso se traduce en saltos y perdida de tiempo, pero a cambio te queda el programa(ejecutable) más corto, ya que a cada llamada solo tienes una función y tendrás que estar saltando hacia ella en cada llamada.

Mas las funciones inline no son una sola, si no que cada vez que la llames ella, se escribe por completo donde la llamas(se hace copias). Si llamas a una función inline estas escribiendo ella justo en ese punto, lo que resumidamente estas evitando los saltos a cambio de un programa más grande.

No se recomienda hacer grandes funciones inline, pero ten presente que si necesitas rendimiento, quizás te interese hacerlas inline a costa de un tamaño más grande del ejecutable.

Pruebe hacer una clase con funciones inline, haga unas cuantas llamadas a esa función, verás como la que es inline te sale el ejecutable más inflado que la que no es inline.

Mire los vídeos. XD

Última edición por vangodp; 15/04/2015 a las 20:01
  #20 (permalink)  
Antiguo 15/04/2015, 20:27
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Muchas gracias por vuestras respuestas. Tengo que estudiarlas bien e irme enterando poco a poco. Hoy he pasado la noche con las funciones y de momento bien.

Mañana tengo bastante lío y no podré quizá contestar o estudiar, pero eso no quiere decir que pase de lo uno o de lo otro! :)

La verdad que creo que estos días me voy a soñar con paréntesis, parámetros, variables, operadores raros, clases, constructores.... demasiados conceptos XD

No obstante vangodp, revisa la pregunta anterior que te hice por favor:

Cita:


Código C++:
Ver original
  1. struct Datos{    
  2.         Datos ( int otroA, int otroB, int otroC, int otroD, int otroE ){
  3.             a = otroA; b = otroB; c = otroC; d = otroD; e = otroE;
  4.         }
  5.         void imprimir(){
  6.             cout << a << ", "<< b << ", "<< c << ", "<< d << ", "<< e << endl;  
  7.         }
  8.        
  9.         int a;
  10.         int b;
  11.         int c;
  12.         int d;
  13.         int e; // podiamos tener 100 datos XDD
  14.     };



¿Cómo es eso de que pareces declarar las variables después de asignarlas? ¿O es válido porque el constructor Datos solo está siendo declarado y definido, pero no utilizado?

Última edición por BramSt; 15/04/2015 a las 21:17
  #21 (permalink)  
Antiguo 15/04/2015, 21:48
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Eso es que dentro de la clase el orden no importa tanto. Primero puedes hacer los constructores y después las variables.

Pero el orden es que primero se carga las variables en la memoria y después se construyen. No hay lógica que sea el contrario ¿no?

Estarás liado por que te has leído que todo debe estar declarado antes de ser usado, y así es como debe ser, pero en las clases eso no se aplica ya que todo esta bajo el mismo ámbito y el orden no importa.

De eso se encarga el preprocesador... De leer y cargar todo en memoria y poner cada cosa en su lugar.

Eso lo entenderás mejor cuando llegues a el tema del puntero this. http://c.conclase.net/curso/?cap=031

En la parte que te dice:
Cita:
Para cada objeto declarado de una clase se mantiene una copia de sus datos, pero todos comparten la misma copia de las funciones de esa clase.

Esto ahorra memoria y hace que los programas ejecutables sean más compactos, pero plantea un problema.

Cada función de una clase puede hacer referencia a los datos de un objeto, modificarlos o leerlos, pero si sólo hay una copia de la función y varios objetos de esa clase, ¿cómo hace la función para referirse a un dato de un objeto en concreto?

La respuesta es: usando el puntero especial llamado this. Se trata de un puntero que tiene asociado cada objeto y que apunta a si mismo. Ese puntero se puede usar, y de hecho se usa, para acceder a sus miembros.
Entonces en realidad lo que ocurre es que no están juntas en la memoria las funciones y las variables si no que tienes grupos de variables(cada una pertenece a su objeto creado) que al necesitar una función en común, esa se dirige hacia dicha función, pasa ese puntero this que dice donde esta las variables a las que tiene que hacer los cálculos, y listo. Internamente no estoy asignando antes de crearlas, es una falsa impresión.

Espero que no te este liando más. Es que el mecanismo de clases al principio te puede parecer extremadamente difícil y si que lo es, pero una vez pilles el tranquillo es que no puedes vivir sin clases nunca más XDD
  #22 (permalink)  
Antiguo 16/04/2015, 02:03
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 11 años, 9 meses
Puntos: 28
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Pero no te pongas a explicarle lo de inline Vangodp, que entonces ya se lía xD

Cita:
Estoy usando, sin saberlo (sin saberlo yo al menos XD), un constructor por defecto que el compilador crea y llama de forma automática, ¿no es así?
C++ obliga a llamar al constructor cuando se crea un objeto. Eso implica que tiene que haber un constructor obligatoriamente (sino, no lo puedes llamar xD).

Ahora bien, en este caso:
Código C++:
Ver original
  1. struct punto{
  2.  
  3.     int a=8;
  4.     int b=10;
  5.  
  6. };

No hay constructores que llamar, aquí el compilador te echa una mano y te lo genera él mismo:

Código C++:
Ver original
  1. struct punto{
  2.  
  3.     int a;
  4.     int b;
  5.  
  6.    punto()
  7.    {
  8.         a = 8;
  9.         b = 10;
  10.    }
  11.  
  12. };


Cita:
Es que primero necesito saber para aclararme:

punto p es una declaración de una variable u objeto de tipo "punto" (como un "int a" de toda la vida, vaya), o es un constructor en sí mismo? Es que claro, con eso de los constructores de copia que se asignaban como variables me descoloco un poco...
punto p crea un objeto de tipo punto.

Otra cosa esque el compilador llame al constructor para crear el objeto.

Cita:
Después, en caso de ser un constructor, ¿es por su especial naturaleza de constructor que, al ser un constructor por defecto, se le llame usando "punto p" y no "punto p()" como entiendo que se haría con cualquier función sin parámetros "normal"?
Sí, es una excepción a la norma.

Tiene dos justificaciones:

- Retrocompatibilidad con C: Las estructuras de C deben seguir funcionando en C++, y ahí no llevaban paréntesis.
- Ambiguedad: punto p() se puede interpretar también como la declaración de una función que devuelve un punto.

Cita:
Después también me choca que para definir el constructor fuera de la estructura, haya que volver a "redeclarar" sus parámetros, de tenerlos... pero eso supongo que es que me tengo que estudiar bien las funciones.
La razón es sencilla: Ambiguedad.

Puedes tener varios constructores, y el compilador tiene que saber a cual te refieres.

Código C++:
Ver original
  1. struct punto{
  2.  
  3.     int a;
  4.     int b;
  5.  
  6.    punto();
  7.    punto(int x,int y);
  8. };
  9.  
  10. punto::punto()      // Constructor sin parámetros
  11. {
  12.     a = 0;
  13.     b = 0;
  14. }
  15.  
  16. punto::punto(int x,int y)     // Constructor con dos enteros
  17. {
  18.      a = x;
  19.      b = y;
  20. }
  #23 (permalink)  
Antiguo 16/04/2015, 06:14
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
C++ obliga a llamar al constructor cuando se crea un objeto. Eso implica que tiene que haber un constructor obligatoriamente (sino, no lo puedes llamar xD).
¿Aun que lo definas fuera es inline?
Ejemplo:

Datos::Datos(int unN){
n = unN;
}

...¿Esto seria inline? Los constructores por defecto no lo se si son inline la verdad.
  #24 (permalink)  
Antiguo 16/04/2015, 07:54
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 11 años, 9 meses
Puntos: 28
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Puedes sugerirselo al compilador:

Código C++:
Ver original
  1. struct Punto
  2. {
  3.     int a,b;
  4.  
  5.     inline Punto();
  6. }
  7.  
  8. Punto:Punto()
  9. {
  10.     a=b=0;
  11. }

PD: Si escribes la clase en un archivo y la implementación en otro archivo... No lo podrás hacer inline.
  #25 (permalink)  
Antiguo 16/04/2015, 08:03
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Iniciado por amchacon Ver Mensaje
Puedes sugerirselo al compilador:
Los compiladores actuales tienden a ignorar el modificador "inline". Hoy en día básicamente va a depender de la configuración de optimización que se le asigne al compilador... independientemente de que la función tenga "inline" o no.

Al menos en la mayoría de los casos funciona así.
  #26 (permalink)  
Antiguo 16/04/2015, 08:36
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Pero mi duda es... ¿Si el constructor es por defecto es inline en teoria?
¿Y si no pongo inline en un constructor definido por mi ese no será inline?

Es que C++ tiene mil reglas... Pff Que jodio es jajaja
  #27 (permalink)  
Antiguo 16/04/2015, 08:36
Avatar de BramSt  
Fecha de Ingreso: abril-2015
Mensajes: 117
Antigüedad: 9 años
Puntos: 5
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Iniciado por vangodp Ver Mensaje
Eso es que dentro de la clase el orden no importa tanto. Primero puedes hacer los constructores y después las variables.

Pero el orden es que primero se carga las variables en la memoria y después se construyen. No hay lógica que sea el contrario ¿no?

Estarás liado por que te has leído que todo debe estar declarado antes de ser usado, y así es como debe ser, pero en las clases eso no se aplica ya que todo esta bajo el mismo ámbito y el orden no importa.

De eso se encarga el preprocesador... De leer y cargar todo en memoria y poner cada cosa en su lugar.

Eso lo entenderás mejor cuando llegues a el tema del puntero this. [URL]http://c.conclase.net/curso/?cap=031[/URL]

En la parte que te dice:
Entonces en realidad lo que ocurre es que no están juntas en la memoria las funciones y las variables si no que tienes grupos de variables(cada una pertenece a su objeto creado) que al necesitar una función en común, esa se dirige hacia dicha función, pasa ese puntero this que dice donde esta las variables a las que tiene que hacer los cálculos, y listo. Internamente no estoy asignando antes de crearlas, es una falsa impresión.

Espero que no te este liando más. Es que el mecanismo de clases al principio te puede parecer extremadamente difícil y si que lo es, pero una vez pilles el tranquillo es que no puedes vivir sin clases nunca más XDD
Hola! Al final saqué un ratillo.

Por partes.

vangodp

Pues efectivamente no me entero de nada XDDDDDDD, pero está bien ir sabiendo que las cosas son por algo, y que mi lío estaba un poco justificado a medias. Supongo que para entender algo así no hay más que una solución: ir poco a poco y echarle horas. Como hasta ahora.

Pero cuanto más aprendo más me gusta.

amchacon

Pero a ver, es que hay algo que no me cuadra:


Cita:
punto p crea un objeto de tipo punto.

Otra cosa esque el compilador llame al constructor para crear el objeto.
Hasta aquí bien, pero es que luego te entiendo que no se hace punto p(), sino punto p, por ser una excepción que yo creí que ocurría en el caso de ser punto p un constructor, esto es, una llamada a una función.

Pero si es un objeto, es que no pintan ahí nada los paréntesis, ¿no?:


Cita:

BramSt:

en caso de ser un constructor, ¿es por su especial naturaleza de constructor que, al ser un constructor por defecto, se le llame usando "punto p" y no "punto p()" como entiendo que se haría con cualquier función sin parámetros "normal"?

Resp:

Sí, es una excepción a la norma.

Tiene dos justificaciones:

- Retrocompatibilidad con C: Las estructuras de C deben seguir funcionando en C++, y ahí no llevaban paréntesis.
- Ambiguedad: punto p() se puede interpretar también como la declaración de una función que devuelve un punto.
Entiendo por otro lado que si cuando hay parámetros sí se ponen, es porque simplemente los utilizas a la vez que declaras el objeto, por pura sintaxis (o eso he sacado de la explicación de dmorill):


Cita:
Cita:
BramSt:

Después, en caso de ser un constructor, ¿es por su especial naturaleza de constructor que, al ser un constructor por defecto, se le llame usando "punto p" y no "punto p()" como entiendo que se haría con cualquier función sin parámetros "normal"?

resp de demorill:

jeje por lo anterior pues no. Pero si el constructor tiene parámetros los llamas directamente cuando declaras la estructura u objeto. ej: punto(4, 5), punto(0, 0);
Quedamos en que no se está llamando a ninguna función en esa sentencia "punto p" ó "punto p(4,5)", ¿verdad? Es la declaración de un objeto del tipo clase que le corresponde.

Y no puede confundirse un punto p (4,5) con una llamada a función con dos parámetros que retorna un punto?

Gracias!

PD: Veo que vosotros también tenéis dudas, eso está bien, así no me siento tan mal por preguntar tanto y sin saber en algunas ocasiones si son preguntas lógicas XD

Última edición por BramSt; 16/04/2015 a las 08:42
  #28 (permalink)  
Antiguo 16/04/2015, 08:45
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Iniciado por BramSt Ver Mensaje
Hasta aquí bien, pero es que luego te entiendo que no se hace punto p(), sino punto p, por ser una excepción que yo creí que ocurría en el caso de ser punto p un constructor, esto es, una llamada a una función.

Pero si es un objeto, es que no pintan ahí nada los paréntesis, ¿no?:
Si el objeto lo vas a crear usando el constructor por defecto no es necesario usar los paréntesis. Y esto es válido tanto para objetos alojados en la pila como para elementos creados con "new" (compilar sin optimizaciones):

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. struct POO
  4. {
  5.   POO( )
  6.   {
  7.     std::cout << "Constructor" << std::endl;
  8.   }
  9. };
  10.  
  11. int main( )
  12. {
  13.   POO p;
  14.   POO* p2 = new POO;
  15. }


Cita:
Iniciado por BramSt Ver Mensaje
Y no puede confundirse un punto p (2,6) con una llamada a función que retorna un punto?
Para evitar este tipo de confusiones, a partir del estándar C++11 se habilitan las llaves {} para inicializaciones: Punto p{2,6}

Cita:
Iniciado por vangodp Ver Mensaje
Pero mi duda es... ¿Si el constructor es por defecto es inline en teoria?
¿Y si no pongo inline en un constructor definido por mi ese no será inline?
Que el código del constructor sea inline o no es relativamente independiente de que lo implementes en la cabecera o de que lo etiquetes con "inline"... la mayor parte de las veces dependerá de lo que decida el compilador. ¿en base a qué? pues en base a la sencillez de su código, por lo que puede tener en cuenta cosas como:

  • Si el código tiene bucles
  • El número de líneas de la función
  • Cantidad de condicionales
  • Cantidad de returns
  • Algúno que se me olvide mencionar
Cuantos más altos sean estos números más dificil es que la función acabe siendo compilada como "inline".



Cita:
Iniciado por vangodp Ver Mensaje
Es que C++ tiene mil reglas... Pff Que jodio es jajaja
La mayor parte de las reglas de C++ sólo son aplicables en casos muy concretos... siguiendo unas costumbres sanas a la hora de diseñar la arquitectura del software y a la hora de escribir el código se pueden conseguir muchos más beneficios que aprovechando todas las "triquiñuelas" que te permite C++.

Última edición por eferion; 16/04/2015 a las 08:51
  #29 (permalink)  
Antiguo 16/04/2015, 09:21
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 11 años, 9 meses
Puntos: 28
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Cita:
Iniciado por BramSt Ver Mensaje
Y no puede confundirse un punto p (4,5) con una llamada a función con dos parámetros que retorna un punto?

Gracias!
No, porque en la declaración de una función pones los tipos de los valores, no lo que valen.
  #30 (permalink)  
Antiguo 16/04/2015, 10:01
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: ¿Para qué necesito un Constructor? (Sí, novato inside XD).

Hola amigo, me gusta ver como estas apasionado por el tema jeje

Cita:
Iniciado por BramSt Ver Mensaje
Hasta aquí bien, pero es que luego te entiendo que no se hace punto p(), sino punto p, por ser una excepción que yo creí que ocurría en el caso de ser punto p un constructor, esto es, una llamada a una función.

Pero si es un objeto, es que no pintan ahí nada los paréntesis, ¿no?:
No es una llamada a una función, si realmente quisiéramos (y pudiéramos) llamar al constructor de punto, sería accediendo a un objeto punto definido y luego usar el operador "." para acceder a sus métodos. Es decir si tenemos:

Código C++:
Ver original
  1. struct punto{
  2. int _x, _y;
  3. void mostrarPunto(){cout << _x << " " << _y << endl; }
  4. punto() : _x(0), _y(0) {}
  5. }

Y queremos usar la función mostrar punto primero debemos crear un objeto (estructura en este caso) del tipo punto. Y luego llamar la función de ese objeto.

Código C++:
Ver original
  1. punto p;
  2. p.mostrarPunto()

Así que si pudiéramos llamar al constructor debería ser algo así:
Código C++:
Ver original
  1. p.punto(0, 0)  // ESTO ESTA MAL, no se llama al constructor es solo un ejmplo

Por eso no es una llamada a una función (constructor).

Cita:
Iniciado por BramSt Ver Mensaje
Entiendo por otro lado que si cuando hay parámetros sí se ponen, es porque simplemente los utilizas a la vez que declaras el objeto, por pura sintaxis (o eso he sacado de la explicación de dmorill):
Si se usan pero no se esta llamando al constructor, el compilador le pasa dichos parámetros al constructor cuando lo declaras.
Cita:
Iniciado por BramSt Ver Mensaje
Quedamos en que no se está llamando a ninguna función en esa sentencia "punto p" ó "punto p(4,5)", ¿verdad? Es la declaración de un objeto del tipo clase que le corresponde.
Y no puede confundirse un punto p (4,5) con una llamada a función con dos parámetros que retorna un punto?
No lo pudiste decir de mejor manera jeje.

un plus jeje, respecto al orden que usa vangodp te comento, c++ diferencia o separa los métodos de los argumentos (variables), así que no importa realmente el orden, ahora bien yo prefiero definiros al principio jeje. Es más diferencia también de lo privado y público, un struct no es más que una clase pero con todo publico, ya cuando estés en ese tema lo entenderás mejor.

Saludos,

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:36.