Domanda

(Credo) Conosco le funzioni di sovraccarico basate sulla costanza:se l'istante è const viene chiamato il metodo const, altrimenti quello non-const.

Esempio (anche a 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;
};

Ho provato/provato a utilizzarlo nel mio codice, ma ho riscontrato alcuni problemi quando il file const i metodi sovraccaricati non hanno la stessa categoria di accesso.Potrebbe essere un cattivo stile, ma ecco un esempio che riflette l'idea di restituire riferimenti per evitare di copiare e utilizzare const per limitare le alterazioni involontarie:

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;
};

Il problema che sto affrontando ora è che voglio che il compilatore attiri il pubblico, const-restituendo la funzione di forma se qualche altra funzione interferisce con le Geometrie, diciamo colorarle in base alla loro area, per cui sarebbe necessario accedere alla forma della Geometria:

// 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];
  }
}

Questo (o qualcosa di simile) fallisce con il seguente errore abbastanza comprensibile:

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

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

(Ho inserito un esempio non compilabile leggermente semplificato su ideone.)

Capisco (in una certa misura) perché questo sta accadendo:g non è const e quindi si suppone che venga chiamato il non-const shape(), che è protectedec, ma ovviamente fallisce.

Quindi immagino che il mio DOMANDA È:Esiste un modo per ottenere una sorta di "fallback" su una funzione const se una funzione non const non è accessibile?

È stato utile?

Soluzione

Esiste un modo per ottenere una sorta di "fallback" su una funzione const se una funzione non const non è accessibile?

NO;la risoluzione del sovraccarico avviene prima del controllo dell'accesso.

Questo non è solo cattivo stile;è un cattivo design.Una funzione getter pubblica lo è concettualmente diverso da una funzione protetta che consente al codice con conoscenza degli interni di modificare lo stato interno dell'oggetto.In generale non è necessario che le due funzioni abbiano tipi restituiti correlati.Pertanto non dovrebbero avere lo stesso nome.

Altri suggerimenti

Puoi usare const_cast per consentire di chiamare la versione const come:

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

Ma sarebbe meglio/più semplice rinominare uno dei metodi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top