Forum: PC-Programmierung [Q] Aufruf einer const Methode auf ein Nonconst Objekt


von Rober (Gast)


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

von Robert (Gast)


Lesenswert?

PS: Es handelt sich um C++, nur das ich es auch im Text erwähne ;)

von Rolf Magnus (Gast)


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.

von Robert (Gast)


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.

von Rolf Magnus (Gast)


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.

von Robert (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.