[Q] Aufruf einer const Methode auf ein Nonconst Objekt

Gast #2166489
Lesenswert?

Hallo,

Ich habe folgendes Konstrukt. Ich habe zwei getter-Methoden in der 
Klasse Foo, eine die einen Nonconst Referenz zurück gibt und eine die 
eine Const Referenz liefert.

Erstere ist für den internen Gebrauch, um nicht einen großen Block Code 
nonconst implementieren zu müssen.
1
class Foo
2
{
3
  private:
4
     Tmp tmp;
5
     Tmp& getTmp() { return tmp; };
6

7
   public:
8
      const Tmp& getTmp() const { return tmp; };
9

10
      void changeTmp();
11
};
12

13
class Bar
14
{
15
    void printTmp(const Tmp& tmp} { ... };
16

17
    void doSomething(Foo& foo) { foo.changeTmp();  printTmp(foo.getTmp()); };
18
};

Dabei habe ich das Problem, dass er bei der Übergabe an Bar::printTmp() 
die private Nonconst Methode aufrufen will, was einen Fehler hervorruft.

Warum ist das so? Ich sollte doch von einem Nonconst Objekt eine 
Const-Methode aufrufen können, oder? Füge ich dem Foo& foo ein const 
hinzu geht die getter Methode, aber klarerweise changeTmp() geht nicht.

Ich hoffe es kann mir wer die Frage beantworten.

Danke - Robert
Gast #2166509
Lesenswert?

Rober schrieb:
> Dabei habe ich das Problem, dass er bei der Übergabe an Bar::printTmp()
> die private Nonconst Methode aufrufen will, was einen Fehler hervorruft.
>
> Warum ist das so?

foo ist non-const, also wird die non-const-Implementation aufgerufen. 
Danach erst prüft der Compiler die Zugriffsrechte und sieht dann, daß 
die Funktion private ist und meldet einen Fehler.

> Ich sollte doch von einem Nonconst Objekt eine Const-Methode aufrufen
> können, oder?

Ja. Dann mußt du foo aber nach const Foo& casten. Warum sollte er für 
ein non-const-Objekt die const-Variante aufrufen, wenn es auch eine 
non-const-Variante gibt?
Wozu überhaupt eine private Zugriffsfunktion? Das Member-Objekt kann 
doch eh direkt benutzt werden.
Gast #2166522
Lesenswert?

Rolf Magnus schrieb:
> foo ist non-const, also wird die non-const-Implementation aufgerufen.

Warum ist das so? Erwartet nicht printTmp() einen Const?

Rolf Magnus schrieb:
> Warum sollte er für
> ein non-const-Objekt die const-Variante aufrufen, wenn es auch eine
> non-const-Variante gibt?

Weil er von außen nur eine const Variante "sieht" habe ich mir gedacht.

Rolf Magnus schrieb:
> Wozu überhaupt eine private Zugriffsfunktion? Das Member-Objekt kann
> doch eh direkt benutzt werden.

Weil das im Programm ein wenig anders aussieht, da steckt eine 
Berechnung dahinter, die ich nicht immer, auch nicht intern, 
implementieren möchte.

Nach außen hin soll es jedoch const sein, da wie gesagt ein großer 
Programmteil sonst unschönerweise nonconst wäre.
Gast #2166545
Lesenswert?

Robert schrieb:
> Rolf Magnus schrieb:
>> foo ist non-const, also wird die non-const-Implementation aufgerufen.
>
> Warum ist das so? Erwartet nicht printTmp() einen Const?

Bei Funktionsüberladung wird die Funktion basierend auf den Parametern 
und dem Objekt gewählt, nicht basierend darauf, was später mit ihrem 
Rückgabewert gemacht wird. Daher spielt printTmp() absolut keine Rolle 
bei der Wahl.

> Rolf Magnus schrieb:
>> Warum sollte er für
>> ein non-const-Objekt die const-Variante aufrufen, wenn es auch eine
>> non-const-Variante gibt?
>
> Weil er von außen nur eine const Variante "sieht" habe ich mir gedacht.

private-Funktionen werden auch "gesehen". Sie sind nur nicht von außen 
aufrufbar. Wie gesagt wird aber zuerst die Funktionsüberladung gemacht 
und danach erst die Prüfung der Zugriffsrechte. Wenn also der Compiler 
sieht, daß die non-const-Funktion private ist, hat er sie bereits 
ausgewählt.

> Rolf Magnus schrieb:
>> Wozu überhaupt eine private Zugriffsfunktion? Das Member-Objekt kann
>> doch eh direkt benutzt werden.
>
> Weil das im Programm ein wenig anders aussieht, da steckt eine
> Berechnung dahinter, die ich nicht immer, auch nicht intern,
> implementieren möchte.
>
> Nach außen hin soll es jedoch const sein, da wie gesagt ein großer
> Programmteil sonst unschönerweise nonconst wäre.

Dann wäre es am einfachsten, diese berechnungs-Funktion anders zu nennen 
und von der public-const-Funktion aus aufzurufen.
Gast #2166570
Lesenswert?

Danke für die ausführliche Antwort :)

Rolf Magnus schrieb:
> Dann wäre es am einfachsten, diese berechnungs-Funktion anders zu nennen
> und von der public-const-Funktion aus aufzurufen.

Umbennenen geht, die Implementierung muss aber trotzdem doppelt 
erfolgen. Denn die Berechnung liefert eine Const Reference, die kann ich 
aber nicht für die interne Methode verwenden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren