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

[SOLUCIONADO] Referencia a función con cláusula const

Estas en el tema de Referencia a función con cláusula const en el foro de C/C++ en Foros del Web. Hola: Tengo la sensación de que este es uno de esos conceptos que tendría que tener más claro pero se ve que no termino de ...
  #1 (permalink)  
Antiguo 17/08/2016, 11:58
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Referencia a función con cláusula const

Hola:

Tengo la sensación de que este es uno de esos conceptos que tendría que tener más claro pero se ve que no termino de entender algo, y como además es algo básico que se usa de continuo, pues me gustaría entenderlo de una vez.

El caso es que creo una función para leer un miembro privado de una clase, así:

Código C++:
Ver original
  1. tipo& LeeDato() const
  2. {
  3.     return dato;
  4. }

Pero el compilador me arroja este error:
error: invalid initialization of reference of type 'tipo&' from expression of type 'const tipo' return dato;
^

Yo entiendo que si retorno una referencia es para poder tener acceso a ella, y que puede haber un sinsentido si por un lado quiero acceder directamente a un miembro y por otro lado no quiero modificarlo, pero no entiendo el por qué de la prohibición.

O es que tal vez no entienda el sentido de una función que retorna una referencia.

Como siempre, gracias!
__________________
Mi calculadora en Qt
  #2 (permalink)  
Antiguo 17/08/2016, 12:21
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 9 meses
Puntos: 27
Respuesta: Referencia a función con cláusula const

El problema que te da el compilador reside en que no tiene sentido devolver una referencia en un método declarado const. Puesto que el const de la derecha significa que el uso de dicho método no modifica la clase y es obvio que si lo hace.

Si la semántica implica que no se pueda modificar entonces añadele const al tipo devuelto.

Código C++:
Ver original
  1. const tipo& leerDato() const {
  2.   return dato;
  3. }
Si la semántica implica que se puede modificar quítale el const de la derecha al método.
  #3 (permalink)  
Antiguo 24/08/2016, 08:47
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Referencia a función con cláusula const

Cita:
Iniciado por xKuZz Ver Mensaje
El problema que te da el compilador reside en que no tiene sentido devolver una referencia en un método declarado const. Puesto que el const de la derecha significa que el uso de dicho método no modifica la clase y es obvio que si lo hace.

Si la semántica implica que no se pueda modificar entonces añadele const al tipo devuelto.

Código C++:
Ver original
  1. const tipo& leerDato() const {
  2.   return dato;
  3. }
Si la semántica implica que se puede modificar quítale el const de la derecha al método.
Gracias xKuZz, por la respuesta. Hice algunas pruebas pero no consigo entender esto del const al final.

Reduciendo la pregunta un poco en plan "hoygan", ¿qué hace realmente el const al final?
__________________
Mi calculadora en Qt
  #4 (permalink)  
Antiguo 24/08/2016, 09:13
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Referencia a función con cláusula const

Cita:
Iniciado por dehm Ver Mensaje
Gracias xKuZz, por la respuesta. Hice algunas pruebas pero no consigo entender esto del const al final.

Reduciendo la pregunta un poco en plan "hoygan", ¿qué hace realmente el const al final?
Ese último const indica que la función no va a modificar el estado del objeto.

Dicho con otras palabras: Si etiquetas una función miembro como const entonces esa función no podrá modificar ninguna variable miembro así como tapoco podrá llamar a funciones no const de la clase.

La excepciones son las siguientes:
  • Variables estáticas: no afectan al estado del objeto, luego podrán modificarse desde cualquier función, sea const, no const o estática.
  • Funciones estáticas: Dado que lo estático no afecta al estado del objeto (son elementos compartidos por todos los objetos de ese tipo), no pueden ser etiquetadas como const. Además estas funciones podrán ser llamadas desde funciones miembro const.
  • variables mutable: mutable es una palabra reservada que indica que la variable en cuestión no se ve afectada por los modificadores "const". Tiene otras connotaciones pero no vienen al caso.

Un pequeño ejemplo:

Código C++:
Ver original
  1. struct POO
  2. {
  3.   int var;
  4.   mutable int mutVar;
  5.   static int staticVar;
  6.  
  7.   void do()
  8.   {
  9.      test(); // ok
  10.      testConst(); // ok
  11.   }
  12.  
  13.   void doConst() const
  14.   {
  15.     test(); // error. doConst es const y no puede llamar a funciones no-const
  16.     testConst();
  17.   }
  18.  
  19.   void test()
  20.   {
  21.     var = 5; // ok
  22.     mutVar = 5; // ok
  23.     staticVar = 5; // ok
  24.     staticFunc(); // ok
  25.   }
  26.  
  27.   void testConst() const
  28.   {
  29.     var = 5; // error. testConst es const y no puede modificar el estado del objeto
  30.     mutVar = 5; // ok
  31.     staticVar = 5; // ok. Los miembros estáticos no afectan al estado del objeto
  32.     staticFunc(); // ok
  33.   }
  34.  
  35.   static void staticConstFunc() const; // Error. Las funciones estáticas no pueden ser const
  36.  
  37.   static void staticFunc()
  38.   {}
  39. };
  40.  
  41. int POO::staticVar = 0;

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #5 (permalink)  
Antiguo 25/08/2016, 02:23
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Referencia a función con cláusula const

Gracias eferion. Perfectamente claro ahora.
Cuando lo estudié, en la web de cconclase, ya decían que la cláusula const tenía su mayor sentido y utilidad cuando hablábamos de funciones miembro, pero no le pillaba el punto.

Marco como solucionado
__________________
Mi calculadora en Qt
  #6 (permalink)  
Antiguo 25/08/2016, 03:41
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Referencia a función con cláusula const

Bueno, aunque ya lo he marcado como solucionado, pregunto si entonces esta es la mejor forma de establecer una función miembro que sólo va a ser de consulta.

Se trataría de una clase que genera una lista y que será sumada desde fuera.

Código C++:
Ver original
  1. #include <iostream>
  2. #include <list>
  3. using namespace std;
  4.  
  5. class lista
  6. {
  7. private:
  8.     list<int> m_lista;
  9.  
  10. public:
  11.     lista(){}
  12.     void hazLista(int tam)
  13.     {
  14.         for (int i=0;i<tam;i++)
  15.         {
  16.             m_lista.push_back(i);
  17.         }
  18.     }
  19.     void mostrar()
  20.     {
  21.         for (auto it = m_lista.begin();it!=m_lista.end();++it)
  22.         {
  23.             cout<<(*it)<<endl;
  24.         }
  25.     }
  26.     const list<int>&LeeLista() const
  27.     {
  28.         return m_lista;
  29.     }
  30.  
  31. };
  32.  
  33. int sumarLista (const list<int>& l)
  34. {
  35.     int suma=0;
  36.     for (auto it = l.begin();it!=l.end();++it)
  37.     {
  38.         suma+=(*it);
  39.     }
  40.     return suma;
  41. }
  42.  
  43. int main()
  44. {
  45.  
  46.     lista l;
  47.     l.hazLista(3);
  48.     l.mostrar();
  49.  
  50.     int resultado = sumarLista(l.LeeLista());
  51.     cout<<"Resultado: "<<resultado<<endl;
  52.     return 0;
  53. }
__________________
Mi calculadora en Qt
  #7 (permalink)  
Antiguo 25/08/2016, 04:04
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Referencia a función con cláusula const

Desde mi punto de vista sí, sería la forma correcta. Yo entiendo que la opción por defecto para todas las funciones miembro debería ser const... y solo aquellas en las que la compilación falle (porque modifican realmente el estado del objeto) deberían ver eliminado dicho atributo.

Por otro lado, si me aceptas una crítica constructiva:

tu versión actual de hazLista añade elementos a la lista en vez de inicializarla. Si la idea es que hazLista resetee la lista podrías dejar la función tal que:

Código C++:
Ver original
  1. void hazLista(int tam)
  2. {
  3.     m_lista = list<int>(tam);
  4.     std::iota(m_lista.begin(), m_lista.end(), 0);
  5. }


la función mostrar tiene demasiado código. El for se puede optimizar bastante y, además, siguiendo lo que he dicho antes, debería ser const:

Código C++:
Ver original
  1. void mostrar() const
  2. {
  3.     for (auto elem : m_lista)
  4.         cout<<elem<<endl;
  5. }

La función sumar_lista no se libra de la crítica tampoco jejejeje. La STL tiene funciones muy útiles para no tener que reescribir una y otra vez los mismos algoritmos:

Código C++:
Ver original
  1. int sumarLista (const list<int>& l)
  2. {
  3.     return std::accumulate(l.begin(), l.end(), 0);
  4. }

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #8 (permalink)  
Antiguo 25/08/2016, 05:05
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Referencia a función con cláusula const

Vale, ahora si que sí.

Aunque la clase es sólo un ejemplo esquemático de lo que quiero hacer, ninguna de las observaciones sobre cómo iterar y o usar funciones de acumulación caen en saco roto!
__________________
Mi calculadora en Qt

Etiquetas: const, referencia
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 12:11.