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

¿Por qué no es obligatorio implementar una función privada?

Estas en el tema de ¿Por qué no es obligatorio implementar una función privada? en el foro de C/C++ en Foros del Web. Estaba haciendo algunas pruebas y me he dado cuenta de que si dentro de una clase tengo declarada una función (un método) en la zona ...
  #1 (permalink)  
Antiguo 16/08/2015, 05:41
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 9 meses
Puntos: 10
¿Por qué no es obligatorio implementar una función privada?

Estaba haciendo algunas pruebas y me he dado cuenta de que si dentro de una clase tengo declarada una función (un método) en la zona privada no me salta el error si no está implementada, cosa que no ocurre con las funciones declaradas en la zona pública.

¿Cuál es la razón de este comportamiento?

¡Saludos y gracias!

Edito:

Obviamente hay que implementar la función para hacer uso de ella, pero a diferencia de los métodos declarados en la zona pública, que he de implementarlos, el compilador me permite no tener que implementar las funciones en la parte privada si no se usan.
__________________
Mi calculadora en Qt

Última edición por dehm; 16/08/2015 a las 13:24
  #2 (permalink)  
Antiguo 17/08/2015, 15:49
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 9 meses
Puntos: 38
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Tecnicamente no sé el por que, pero sé que por ejemplo en los patrones singleton, se suelen declarar los constructores de la clase privadamente, luego se crea una función que instancia una sola vez la clase al llamarla, si intentas llamarla más de una vez lo que hace es devolverte el puntero a la primera instancia. Supongo que es para prohibir que llamemos esa función a lo mejor en caso de herencia o lo que sea. XD

Un ejemplo podría ser el "caso penguino" XD. un penguino es una ave, pero no vuela, entonces si penguino hereda de la clase ave, no debería poder usar el método volar heredado. Una solución? "Redeclarar" el método volar como privado. Aun que no estoy tan seguro de lo que he dicho es solo cuestión de probar. ;)

La resposta corta seria..¡Para impedir que llamemos esa función! Como es privada no necesita cuerpo >_<. Ahora si esta como privada y intentas llamarla de la parte publica, entonces es un error tuyo, por que no tiene sentido no crees.

A ver si alguien nos aclara eso XD
  #3 (permalink)  
Antiguo 18/08/2015, 01:36
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 9 meses
Puntos: 10
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Hola vangodp:

Realmente mi duda es mucho mas tonta que todo eso.
Es simplemente que me llama la atención el hecho de que yo puedo crear una clase, definir un método privado, no implementarlo, y que el compilador no se queje por ello, cosa que no ocurre con un método declarado en la zona pública, en el que tengo que implementarlo o si no el compilador me dará error.

De todas formas acabo de probar y en C::B me deja declarar funciones en cualquier parte (pública y privada) y no implementarlas. Y el compilador no se quejará de ello, excepto si una instancia de la clase hace uso de un método no implementado.

Es decir, puedo hacer esto:
Código C++:
Ver original
  1. #include<iostream>
  2.     using namespace std;
  3.  
  4.     class miClase
  5.     {
  6.     public:
  7.         miClase(){}
  8.         void miMetodo();
  9.  
  10.     private:
  11.  
  12.     };
  13.  
  14.     int main()
  15.     {
  16.         miClase eme;
  17.         //eme.miMetodo();
  18.  
  19.     }

Pero si descomento la última línea, el compilador se quejará porque obviamente no está implementado el método.

Sin embargo en Qt no me deja tener funciones no implementadas en la zona pública aunque sí en la privada. Es un comportamiento un poco diferente.
Miraré a ver si se trata de alguna opción del compilador, porque tanto mi C::B como mi Qt compilan con gcc.

Bueno, muchas gracias por la respuesta. Ya entiendo por fin el patrón Singleton
__________________
Mi calculadora en Qt
  #4 (permalink)  
Antiguo 18/08/2015, 07:09
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 9 meses
Puntos: 38
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

No es una opción del compilador, al menos lo de declararla en la parte privada, ya lo del public no se para que sirve, seguramente para hacer el proceso inverso, o sea que si hereda algo como privado lo podamos hacer publico, aun que de ese ultimo no lo probé. XD

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3. class ave {
  4.     public:
  5.         ave(){}
  6.         ~ave(){}
  7.         void volar();
  8.     private:
  9.    
  10. };
  11.  
  12. class penguino: public ave {
  13.     public:
  14.         penguino(){}
  15.         ~penguino(){}
  16.        
  17.     private:
  18.         void volar();
  19. };
  20.  
  21. void ave::volar(){
  22.     cout << "flop..flop..flop XD" << endl;
  23. }
  24.  
  25.  
  26. int main (){
  27.     ave unaAve;
  28.     penguino bigFoot;
  29.     cout << "ave";
  30.     unaAve.volar();
  31.    
  32.     //penguino no puede volar el metodo volar es privado
  33.     //bigFoot.volar();
  34.    
  35.     cin.ignore();
  36.     return 0;
  37. }

Edit
He probado en codeblocks y no me permite lo de la parte publica, será el compilador.
Puse el método volar como privado en la clase principal, y en la clase base puse como public volar. El erro dice que es una referencia indefinida, así que supongo que sea por el compilador.
Yo utilizo la versión 5 de gcc. ¿Cual es la versión de tu compilador en codeblocks? ¿Usas el codeblocks por defecto?
Yo utilizo una versión que se descarga desde el foro que se llama "codeblocks nightly", se actualiza a menudo. Y lo uso conjuntamente con el compilador mingw-w64 que se descarga aparte desde internet.

Última edición por vangodp; 18/08/2015 a las 07:23
  #5 (permalink)  
Antiguo 21/08/2015, 02:27
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 9 meses
Puntos: 10
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Hola vangodp:

Pues el gcc que tengo es el 4.8.4.

Y el CodeBlocks es el 13.12

Como esto se actualiza sólo, pues....a mi lo que me ponen
__________________
Mi calculadora en Qt
  #6 (permalink)  
Antiguo 24/08/2015, 00:49
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 9 meses
Puntos: 204
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Si tu declaras una función en la parte privada de una clase dicha función pasa a ser accesible únicamente por la propia clase... su ámbito de uso es tremendamente limitado. En este caso, el compilador no dará error... esperará a encontrar un uso de dicha función para mostrarte un mensaje de error. Este comportamiento se aprovechaba hasta la llegada de C++11 para deshabilitar, por ejemplo, el constructor por defecto (basta con declararlo en la parte privada y olvidarse de la implementación... mientras no intentes llamarlo desde la propia clase el código compilará).

Si, en cambio, declaras la función en la parte pública esa función pasa a ser accesible desde cualquier parte del código... como es hasta posible que la clase acabe compilada en una librería (me da igual que fuese estática o dinámica) entonces el compilador obliga a que la función tenga implementación. Imagínate que compilas una DLL y no te da problemas... luego distribuyes esa DLL y los clientes se empiezan a quejar diciendo que no se puede usar tu DLL porque les da problemas de compilación...

Si el asunto no ha quedad claro se admiten preguntas :P

Un saludo.
  #7 (permalink)  
Antiguo 24/08/2015, 04:55
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 9 meses
Puntos: 38
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Cita:
..esperará a encontrar un uso de dicha función para mostrarte un mensaje de error
Es que si la llamamos después de declararla como private nos merecemos un palo en el cuero jaja.

Cita:
Este comportamiento se aprovechaba hasta la llegada de C++11
¿Por que dices "...'se aprovechaba' hasta la llegada de C++11"?¿Es que tiene c++11 otro mecanismo e no podemos declarar como privado los constructores? Si no entiendo mal eso no es cierto, ya que cout, cin, e cerr siguen el "Patrón Singletón" ya que nunca tenemos que crear un objeto de su tipo para poder usar la consola, por esa razón supongo que sus constructores serán privados. Ya no sé que pensar.

Eso lo vi en un vídeo por Internet, el tipo parecía un fiera, como tú eferion. Creo que el vídeo es ese: https://www.youtube.com/watch?v=peg5...ature=youtu.be

En el vídeo, el locutor intenta dar motivos para que no usemos nunca ese tal Patrón Singletón, pero la verdad en algunos casos sí que le he visto algo de utilidad, sobre todo a la hora de pasar "punterillos" a si mismo con el tal miembro "instance()" que es el que se encarga de llamar al constructor privado evitando así crear más de una instancia de la clase. >_<

Si existe algo mejor me gustaría saberlo. Gracias! =D
  #8 (permalink)  
Antiguo 24/08/2015, 05:21
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 9 meses
Puntos: 204
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Cita:
Iniciado por vangodp Ver Mensaje
Es que si la llamamos después de declararla como private nos merecemos un palo en el cuero jaja.
Si lo haces el compilador te avisará de que estás intentando llamar a una función privada ;)

Cita:
Iniciado por vangodp Ver Mensaje
¿Por que dices "...'se aprovechaba' hasta la llegada de C++11"?¿Es que tiene c++11 otro mecanismo e no podemos declarar como privado los constructores?
C++11 incorpora al lenguaje, entre otras cosas, dos palabras reservadas: default y deleted:

  • default obliga a que el compilador implemente la función por defecto.
  • deleted marca la función como borrada, lo cual impide que el compilador pueda crear una versión por defecto.


En qué afecta esto?


Veamos:
Código C++:
Ver original
  1. class Test
  2. {
  3.   public:
  4.     Test( ) = deleted;
  5.  };
  6.  
  7.  
  8.  
  9. int main( )
  10. {
  11.   Test test; // Error de compilación... el constructor por defecto no es accesible
  12.  
  13. }

Esto no se podía hacer en las versiones anteriores de C++, entonces el truco para deshabilitar un constructor que no se usaba era marcarlo como private y olvidarse de su implementación... si nadie lo llama el código funciona.

¿Hay alguna diferencia adicional entre un método y otro? SI y es que "deleted" le indica al compilador que no debe crear la función por defecto. Digamos que en con el truco usado en versiones anteriores a C++11 el compilador podía acabar creando código que nunca se usaba.

Por cierto, deleted se puede usar con cualquier función... esto puedes usarlo para deshabilitar funciones en clases hijas (en vez de marcarlas como privadas).

¿Y qué pasa con default? Bueno, como sabrás, si tu implementas un constructor hay otros constructores que, implicamente, no se van a implementar, por lo que si necesitas hacer uso de los mismos te toca poner a tí el código... con esta palabra clave obligas al compilador a crear el código para dicho constructor. Además, también puede ser utilizado para remarcar que dicho constructor está disponible:

Código C++:
Ver original
  1. class Test
  2. {
  3.   public:
  4.     Test() = default; // No hace falta implementación y queda claro que este constructor está disponible en esta clase
  5. };

Cita:
Iniciado por vangodp Ver Mensaje
En el vídeo, el locutor intenta dar motivos para que no usemos nunca ese tal Patrón Singletón, pero la verdad en algunos casos sí que le he visto algo de utilidad, sobre todo a la hora de pasar "punterillos" a si mismo con el tal miembro "instance()" que es el que se encarga de llamar al constructor privado evitando así crear más de una instancia de la clase. >_<
El patrón singleton es un tanto polémico. Debido a su extrema facilidad de uso es un azucarillo muy recurrido... a costa de la usabilidad del programa. Lo que incluyas en un singleton no tendrá dependencias dentro del código... cualquiera puede modificar su contenido, no hay trazas, no hay control de acceso. Si tienes un singleton no tienes forma de evitar que otro programador haga uso de sus funciones aún cuando no debiera.

Hay situaciones en las que puede ser necesario tener un singleton, pero merece la misma consideración que las variables globales... hay que intentar evitarlas. Para este punto no puedo darte soluciones genéricas, cada proyecto tiene sus particularidades y habría que dar más bien soluciones concretas a problemas concretos.

Un saludo
  #9 (permalink)  
Antiguo 24/08/2015, 09:00
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 9 meses
Puntos: 10
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Cita:
Iniciado por eferion Ver Mensaje
Si tu declaras una función en la parte privada de una clase dicha función pasa a ser accesible únicamente por la propia clase... su ámbito de uso es tremendamente limitado. En este caso, el compilador no dará error... esperará a encontrar un uso de dicha función para mostrarte un mensaje de error. Este comportamiento se aprovechaba hasta la llegada de C++11 para deshabilitar, por ejemplo, el constructor por defecto (basta con declararlo en la parte privada y olvidarse de la implementación... mientras no intentes llamarlo desde la propia clase el código compilará).

Si, en cambio, declaras la función en la parte pública esa función pasa a ser accesible desde cualquier parte del código... como es hasta posible que la clase acabe compilada en una librería (me da igual que fuese estática o dinámica) entonces el compilador obliga a que la función tenga implementación. Imagínate que compilas una DLL y no te da problemas... luego distribuyes esa DLL y los clientes se empiezan a quejar diciendo que no se puede usar tu DLL porque les da problemas de compilación...

Si el asunto no ha quedad claro se admiten preguntas :P

Un saludo.

Hola eferion:

Perfectamente explicado y entendido.
Sin embargo, tras mi último "descubrimiento", cambio la pregunta a:
¿Entonces por qué me deja tener una función NO implementada en la parte pública?
(Como en el ejemplo que pongo)
__________________
Mi calculadora en Qt
  #10 (permalink)  
Antiguo 24/08/2015, 09:21
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 9 meses
Puntos: 204
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

A ver, hoy me he reincorporado de mis vacaciones y aún estoy en fase de reconexión. Al leer los primeros mensajes he dado una respueta demasiado acelerada... voy a rreglar el desaguisado.

Como comenté en otro hilo, la implementación de una clase puede estar repartida en infinitos archivos, siempre y cuando cada función esté implementada de una vez. Debido a que el proceso de compilación se realiza fichero a fichero, tratando cada uno de forma independiente, el compilador no puede saber, en tiempo de compilación, si una función tiene implementación o no.

En tiempo de linkado es cuando se podrían evaluar este tipo de problemas... pero si el compilador no detecta llamadas a esa función entonces no va a mostrar ningún error porque, sencillamente, el código generado va a funcionar correctamente.
  #11 (permalink)  
Antiguo 24/08/2015, 09:27
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 9 meses
Puntos: 10
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Ja ja....tiene toda su lógica.

Pero ¿puede ser que haya una opción en el compilador que prevenga de tales cosas?

Lo digo porque el ejemplo que pongo compila en CodeBlocks y no el QtCreator, aunque ambos usan GCC....

Conste que yo prefiero que no compile, para que no se me pasen por alto estos errores, que por otra parte se dan en un contexto muy determinado.
En mi caso, estaba haciendo copia/pega de un libro de Qt.
__________________
Mi calculadora en Qt
  #12 (permalink)  
Antiguo 24/08/2015, 09:37
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 9 meses
Puntos: 204
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Si no se encuentra la implementación el compilador puede generar un warning... si la compilación se configura para que trate los warnings como errores entonces la compilación fallará... eso sí, esto, como he comentado, únicamente se puede detectar durante el linkado (me he acostumbrado a ponerlo con 'k' por su uso en inglés), por lo que no te fallará al crear una librería estática pero si al compilar un programa o una DLL
  #13 (permalink)  
Antiguo 24/08/2015, 09:57
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 9 meses
Puntos: 38
Respuesta: ¿Por qué no es obligatorio implementar una función privada?

Ok compañero, gracias por explicar lo del "deleted" y el "default".
Con el C++11 aun no me he puesto ya que sigo aun con el anterior, que ya me hace un quebradero de cabeza, pero el simple fato de saber que existen algunas cosas, en su momento pueden me servir mucho. =)

Etiquetas: funcion, implementar, obligatorio
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 00:33.