Warum muss ich überladene virtuelle Funktionen neu deklarieren?

Nov 26 2020

Ich habe eine Basisklasse mit zwei überladenen Funktionen f(void)und f(int). Die Klasse wird durch Aufrufen Derivedimplementiert . implementiert nur.f(int)f(void)Derived2f(void)

Der Compiler lehnt die Implementierung ab, Derived::f(int)weil er aufrufen möchte, f(int)aber ich habe keine Argumente angegeben, weil ich aufrufen möchte f(void). Warum lehnt der Compiler es ab? Warum virtual int f(void) = 0;behebt das Hinzufügen der Zeile mein Problem?

class Base
{
public:
  explicit Base(void) {}
  virtual ~Base(void) {}

  virtual int f(void) = 0;
  virtual int f(int i) = 0;
};

class Derived : public Base
{
public:
  // provide implementation for f(int) which uses f(void). Does not compile.
  virtual int f(int i) {puts("Derived::f(int)"); return f();}
  // code only compiles by adding the following line.
  virtual int f(void) = 0;
};

class Derived2 : public Derived
{
public:
  // overwrite only f(void). f(int) is implemented by Derived.
  virtual int f(void) {puts("Derived2::f(void)"); return 4;}
};

int main(void)
{
  Base * p = new Derived2();
  int i0 = p->f();  // outputs Derived2::f(void) and returns 4
  int i1 = p->f(1); // outputs "Derived::f(int) Derived2::f(void)" and return 4
  delete p;
  return 0;
}

Antworten

5 songyuanyao Nov 26 2020 at 08:18

Derived::fversteckt Base::fs. Gegeben return f();im Körper Derived::f(int), der Name fwird im Rahmen gefunden Derived, dann Namenssuche stoppt. Die Namen in Basewerden nicht gefunden und nehmen an der Überlastungsauflösung teil.

Die Namenssuche untersucht die Bereiche wie unten beschrieben, bis mindestens eine Deklaration jeglicher Art gefunden wird. Zu diesem Zeitpunkt wird die Suche gestoppt und es werden keine weiteren Bereiche untersucht.

Sie können hinzufügen using Base::f;, um den Namen von Basein den Bereich von einzuführen Derived.

class Derived : public Base
{
public:
  using Base::f;

  // provide implementation for f(int) which uses f(void).
  virtual int f(int i) {puts("Derived::f(int)"); return f();}
};