www.mikrocontroller.net

Forum: PC-Programmierung Überladen virtueller Funktionen C++


Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Kann mir jemand erklären, warum ich im Beispiel unten die überladene 
Funktion "doAmazingStuff" mit einem Parameter für ein Objekt der 
abgeleiteten Klasse nicht aufrufen kann?
#include <iostream>

class A
{
public:
  void doBoringStuff(double a) { doAmazingStuff(a, a/2); };

public:
  void doAmazingStuff(double a) { doAmazingStuff(a, a/2); };
  virtual void doAmazingStuff(double a, double b) = 0;
};

class B : public A
{
public:
  void doAmazingStuff(double a, double b) { std::cout << a << " " << b << std::endl; };
};

int main()
{
  A* a = new B;
  // OK
  a->doAmazingStuff(8);

  B b;
  // OK
  b.doBoringStuff(8);
  // Compiler error
  b.doAmazingStuff(8);

  return 0;
}

Vielen Dank!
Tobias

Autor: Semikoln (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher Compiler? Da sind doch Syntax-Fehler drin, oder?

Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Standard GNU Compiler.

Keine Syntaxfehler.

Nur die Zeile "b.doAmazingStuff(8);" erzeugt folgenden Fehler:

test.cpp:29: error: no matching function for call to 
‘B::doAmazingStuff(int)’
test.cpp:16: note: candidates are: virtual void 
B::doAmazingStuff(double, double)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank! Das beantwortet meine Frage.

Autor: Semikoln (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias schrieb:
> Keine Syntaxfehler.
>
> Nur die Zeile "b.doAmazingStuff(8);" erzeugt folgenden Fehler:
>
> test.cpp:29: error: no matching function for call to
> ‘B::doAmazingStuff(int)’
> test.cpp:16: note: candidates are: virtual void
> B::doAmazingStuff(double, double)

Ja aber bitte schön!

Überladen wird der 'double, double' und aufgerufen mit 'double' (oder 
int). Das ist doch ein Fehler, oder?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und um die Frage nach dem 'warum' zu beantworten.

Das ist eine direkte Folge des Aufsuchalgorithmuses, den der Compiler 
benutzt um die richtige Funktion auszuwählen.

Der Compiler beginnt bei der abgeleiteten Klasse und arbeitet sich in 
Richtung Basisklasse vor. Er ist dabei auf der Suche nach der ersten 
Klasse, die eine oder mehrere Funktionen des angegebenen Namens enthält. 
Ist die Klasse erst einmal gefunden, dreht sich die Entscheidung nur 
noch darum, welche der Funktionen mit ihrer Parameterliste am besten zu 
den Argumenten passt. Falls gar keine passt, dann ist das ein Fehler, 
der Compiler beginnt nicht erneut sich in Richtung Basisklasse 
vorzuarbeiten und in einer Basisklasse eine besser passende Funktion zu 
finden.

In der Kurzfassung:
  zuerst wird ausgewählt, welche Klasse zuständig ist.
  dann wird aus dem Satz von verfügbaren Funktionen die am besten
  passende ausgewählt.


Da deine Klasse B eine Funktion
   void doAmazingStuff(double a, double b)
enthält, ist sie die Klasse unter deren Funktionen 'doAmazingStuff' 
ausgewählt wird.
Und da gibt es nun mal nur die eine, die 2 double nimmt.
Das ist aber unvereinbar mit
    b.doAmazingStuff(8);
und daher gibts den Fehler.

Die Klasse A, mit ihrer zusätzlichen Funktion doAmazingStuff, war 
überhaupt nie auch nur Kandidat, der in Betracht gezogen worden wäre.

Daher sagt man auch: Ein Funktion in einer abgeleiteten Klasse überdeckt 
(engl.: to hide) alle Funktionen gleichen Namens in den Basisklassen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.