Frage

(Ich glaube) Ich kenne das Überladen von Funktionen basierend auf Konstanz:Wenn der Zeitpunkt const ist, wird die const-Methode aufgerufen, andernfalls die nicht-const-Methode.

Beispiel (auch bei Idee):

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

Ich habe versucht, dies in meinem Code zu nutzen, bin aber auf einige Probleme gestoßen, als die const Überladene Methoden haben nicht dieselbe Zugriffskategorie.Es mag vielleicht ein schlechter Stil sein, aber hier ist ein Beispiel, das die Idee widerspiegelt, Referenzen zurückzugeben, um ein Kopieren und Verwenden zu vermeiden const um unbeabsichtigte Änderungen einzuschränken:

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

Das Problem, mit dem ich jetzt konfrontiert bin, besteht darin, dass ich möchte, dass der Compiler die Öffentlichkeit abholt. const-Rückgabe der Formfunktion, wenn eine andere Funktion die Geometrien stört, z. B. färben Sie sie nach ihrer Fläche ein, wofür auf die Form der Geometrie zugegriffen werden müsste:

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

Dies (oder etwas Ähnliches) schlägt mit dem folgenden einigermaßen verständlichen Fehler fehl:

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

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

(Ein leicht vereinfachtes Nicht-Kompilierungsbeispiel habe ich unter bereitgestellt Idee.)

Ich verstehe (bis zu einem gewissen Grad), warum das passiert:g ist nicht const und daher soll angeblich die nicht konstante Form () aufgerufen werden, die Protectec ist – aber das schlägt offensichtlich fehl.

Also denke ich, mein FRAGE Ist:Gibt es eine Möglichkeit, auf eine konstante Funktion zurückzugreifen, wenn auf eine nicht konstante Funktion nicht zugegriffen werden kann?

War es hilfreich?

Lösung

Gibt es eine Möglichkeit, auf eine konstante Funktion zurückzugreifen, wenn auf eine nicht konstante Funktion nicht zugegriffen werden kann?

NEIN;Die Überlastungsauflösung erfolgt vor der Zugriffsprüfung.

Das ist nicht nur schlechter Stil;Es ist schlechtes Design.Eine öffentliche Getter-Funktion ist konzeptionell anders von einer geschützten Funktion, die es Code mit Kenntnis der Interna ermöglicht, den internen Zustand des Objekts zu ändern.Im Allgemeinen müssen die beiden Funktionen nicht einmal verwandte Rückgabetypen haben.Daher sollten sie nicht denselben Namen haben.

Andere Tipps

Sie können verwenden const_cast um den Aufruf der const-Version zu ermöglichen als:

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

Es wäre jedoch besser/einfacher, eine der Methoden umzubenennen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top