Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: xaps en 13 Noviembre 2013, 02:10 am



Título: [SOLUCIONADO] C++ - Error al usar "const" en funciones de una clase.
Publicado por: xaps en 13 Noviembre 2013, 02:10 am
Buenas. Tengo un pequeño problema con una clase Matriz que estoy desarrollando en C++. Según tengo entendido, cuando un parámetro de una función va a ser constante durante toda la ejecución de esa función, se pasa ese parámetro en forma constante y por referencia. Bien, el problema es que en mi clase matriz, me salta un error de compilación en la copiadora-constructora por el uso del tag const en las tres consultoras de la clase (si lo haces desde fuera la clase, los métodos que hacen saltar el error si que funcionan). El error es el siguiente (compilado con g++):

Código:
In file included from multiplicacion_matriz.cpp:1:0:
Matriz.cpp: In copy constructor ‘Matriz::Matriz(const Matriz&)’:
Matriz.cpp:54:37: error: passing ‘const Matriz’ as ‘this’ argument of ‘const int Matriz::consultar_filas()’ discards qualifiers [-fpermissive]
Matriz.cpp:55:43: error: passing ‘const Matriz’ as ‘this’ argument of ‘const int Matriz::consultar_columnas()’ discards qualifiers [-fpermissive]
Matriz.cpp:68:38: error: passing ‘const Matriz’ as ‘this’ argument of ‘const int Matriz::consultar(int, int)’ discards qualifiers [-fpermissive]
Matriz.cpp: In member function ‘void Matriz::sumar(const Matriz&)’:
Matriz.cpp:101:72: error: passing ‘const Matriz’ as ‘this’ argument of ‘const int Matriz::consultar(int, int)’ discards qualifiers [-fpermissive]
Matriz.cpp: In member function ‘void Matriz::multiplicar(const Matriz&, int)’:
Matriz.cpp:111:75: error: passing ‘const Matriz’ as ‘this’ argument of ‘const int Matriz::consultar(int, int)’ discards qualifiers [-fpermissive]

Y el código de la clase en la que salta el error es este:
Código
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. class Matriz {
  7.  
  8. private:
  9.  
  10.  int filas;
  11.  int columnas;
  12.  int **matr;
  13.  
  14. public:
  15.  
  16.  //Constructora
  17.  Matriz(int filas, int columnas);
  18.  
  19.  //Constructora-copiadora
  20.  Matriz(const Matriz &mat);
  21.  
  22.  //Destructora
  23.  ~Matriz();
  24.  
  25.  //Consultoras
  26.  const int consultar_filas();
  27.  const int consultar_columnas();
  28.  const int consultar(int fila, int columna);
  29.  
  30.  //Modificadora
  31.  void modificar(int fila, int columna, int x);
  32.  void sumar(const Matriz &mat);
  33.  void multiplicar(const Matriz &mat, int pos);
  34.  
  35.  //Entrada / Sortida
  36.  void leer();
  37.  void escribir();
  38. };
  39.  
  40. Matriz::Matriz(int filas, int columnas)
  41. {
  42.  this->filas = filas;
  43.  this->columnas = columnas;
  44.  
  45.  matr = new int* [filas];
  46.  for (int i = 0; i < filas; ++i)
  47.  {
  48.    matr[i] = new int [columnas];
  49.  }
  50. }
  51.  
  52. Matriz::Matriz(const Matriz &mat)
  53. {
  54.  this->filas = mat.consultar_filas();
  55.  this->columnas = mat.consultar_columnas();
  56.  
  57.  matr = new int* [filas];
  58.  for (int i = 0; i < filas; ++i)
  59.  {
  60.    matr[i] = new int [columnas];
  61.  }
  62.  
  63.  
  64.  for (int i = 0; i < filas; ++i)
  65.  {
  66.    for (int j = 0; j < columnas; ++j)
  67.    {
  68.      matr[i][j] = mat.consultar(i, j);
  69.    }
  70.  }
  71. }
  72.  
  73. Matriz::~Matriz()
  74. {
  75.  delete[] matr;
  76. }
  77.  
  78. const int Matriz::consultar_filas()
  79. {
  80.  return this->filas;
  81. }
  82.  
  83. const int Matriz::consultar_columnas()
  84. {
  85.  return this->columnas;
  86. }
  87.  
  88. const int Matriz::consultar(int fila, int columna)
  89. {
  90.  return this->matr[fila][columna];
  91. }
  92.  
  93. void Matriz::modificar(int fila, int columna, int x)
  94. {
  95.  matr[fila][columna] = x;
  96. }
  97.  
  98. void Matriz::sumar(const Matriz &mat)
  99. {
  100.  for (int i = 0; i < filas; ++i)
  101.    for (int j = 0; j < columnas; ++j) matr[i][j] += mat.consultar(i, j);
  102. }
  103.  
  104. void Matriz::multiplicar(const Matriz &mat, int pos)
  105. {
  106.  for (int i = 0; i < filas; ++i)
  107.  {
  108.    for (int j = 0; j < columnas; ++j)
  109.    {
  110.      int res = 0;
  111.      for (int k = 0; k < pos; ++k) res += matr[i][k] * mat.consultar(k, j);
  112.      matr[i][j] = res;
  113.    }
  114.  }
  115. }
  116.  
  117. void Matriz::leer()
  118. {
  119.  for (int i = 0; i < filas; ++i)
  120.    for (int j = 0; j < columnas; ++j) cin >> matr[i][j];
  121. }
  122.  
  123. void Matriz::escribir()
  124. {
  125.  for (int i = 0; i < filas; ++i)
  126.  {
  127.    for (int j = 0; j < columnas; ++j) cout << matr[i][j] << " ";
  128.    cout << endl;
  129.  }
  130. }
  131.  

Si elimino la etiqueta const de las tres funciones que devuelven un error al compilar, el error desaparece, pero me gustaría saber el porque de este error, ya que los métodos que utilizo con el objeto constante no son modificadores, e incluso he probado a hacer los métodos constantes por si acaso, pero ni con esas.

Gracias!



Al final he conseguido averiguar cual era el problema. Si colocas la etiqueta const delante de una función, estás indicando que el resultado de ésta sera de un tipo constante. En cambio, si lo colocas detrás, estás diciendo que la función no modificará ningún parámetro. Por lo tanto, la solución al error es cambiar las etiquetas de sitio y ponerlas detrás de la función. De esta manera le aseguras al compilador que esa función no modificará ningún parámetro.

Saludos


Título: Re: C++ - Error al usar "const" en funciones de una clase.
Publicado por: xaps en 18 Noviembre 2013, 10:37 am
He modificado el título y el cuerpo del post, ya que aun no he conseguido resolver este problema. Concretamente, he especificado más el problema y he añadido el código directamente al post (antes estaba en pastebin) y nuevos intentos que he hecho por entender el problema y solucionarlo.

Las funciones que hacen saltar el error son las de la línea 59 a la 72 (solo cuando se llaman desde la constructora-copiadora). En cuanto pueda separaré el código de la clase para mejorar su organización (tengo un examen de aquí unas horas, esta tarde como muy tarde subiré una mejor implementación).

Si alguien puede echarle un ojo, le estaré muy agradecido.

Saludos

EDITO:

Ya he modificado el código, separando la especificación de la implementación. También he actualizado el mensaje de error al nuevo código.