Pregunta

(Creo) Sé sobre la sobrecarga de funciones basadas en Const-Ness: Si el instante es const, se llama al método Const, de lo contrario el no-const.

Ejemplo (también en Ideone ):

#include <iostream>

struct S
{
  void print() const { std::cout << "const method" <<std::endl };
  void print()       { std::cout << "non-const method" <<std::endl };
};

int main()
{
  S const s1;
  s1.print(); // prints "const method"
  S s2;
  s2.print(); // prints "non-const method"
  return 0;
};

Intento / Intenté hacer uso de eso en mi código, pero se encontró con algunos problemas cuando los métodos sobrecargados de const no tienen la misma categoría de acceso. Puede ser un estilo malo, pero aquí hay un ejemplo que refleja la idea de devolver las referencias para evitar la copia y el uso de const para limitar las alteraciones involuntarias:

struct Color;
struct Shape
{
  double area;
};

class Geometry
{
public:
  // everybody can alter the color of the geometry, so 
  // they get a mutable reference
  Color& color() { return m_color; };

  // not everybody can alter the shape of the Geometry, so
  // they get a constant reference to the shape.
  Shape const& shape() const { return m_shape; };

protected:
  // derived classes can alter the shape, so they get 
  // access to the mutable reference to alter the shape.
  Shape & shape() { return m_shape; };

private:
  Shape m_shape;
  Color m_color;
};

El problema que estoy enfrentando ahora es que quiero que el compilador pueda recoger la función pública, const-devuelto. Si alguna otra función se interpreta con las geometrías, dígalos de color por su área, para la cual esto tendría que acceder a la Forma de la geometría:

// this one fails
void colorByArea() {
  for( Geometry g : geometryList )
  { g.color() = colorMap[g.shape().area]; }
}

// this one is a clunky workaround
void colorByArea() {
  for( Geometry g : geometryList )
  { 
    Geometry const& g_const = g;
    g.color() = colorMap[g_const.shape().area];
  }
}

Esto (o algo similar) falla con el siguiente error bastante comprensible:

‘Shape& Geometry::shape()’ is protected 
  Shape & shape() { return m_shape; };

^ error: within this context
  g.color() = colorMap[g.shape().area];

(Puse un ejemplo sin compilación ligeramente simplificado en Ideone .)

Hago (hasta cierto punto) ¿Por qué esto está sucediendo: g no es const y, por lo tanto, la forma que no es const (), que es protectora, se debe llamar, pero eso obviamente falla.

Supongo que mi pregunta es: ¿Hay alguna manera de obtener algún tipo de "retroceder" a una función constituida si no es accesible una función que no es const?

¿Fue útil?

Solución

¿Hay alguna manera de obtener algún tipo de "retroceder" a una función constituida si no se puede acceder a una función que no es const?

no;La resolución de sobrecarga se produce antes de la verificación de acceso.

Este no es solo un mal estilo;Es un mal diseño.Una función de Getter Public es conceptualmente diferente de una función protegida que permite el código con el conocimiento de los internales Modifique el estado interno del objeto.En general, las dos funciones ni siquiera necesitan tener tipos de devolución relacionados.Por lo tanto, no deben tener el mismo nombre.

Otros consejos

Puede usar const_cast para permitir llamar a la versión const como:

int main()
{
  S s2;
  const_cast<const S&>(s2).print(); // prints "const method"
  return 0;
};

Pero sería mejor / más sencillo cambiar el nombre de uno del método.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top