Aufruf virtuelle Funktionen in Konstruktoren

Angenommen ich habe zwei C++ - Klassen:

class A
{
public:
  A() { fn(); }

  virtual void fn() { _n = 1; }
  int getn() { return _n; }

protected:
  int _n;
};

class B : public A
{
public:
  B() : A() {}

  virtual void fn() { _n = 2; }
};

Wenn ich den folgenden code schreiben:

int main()
{
  B b;
  int n = b.getn();
}

Könnte man erwarten, dass n auf 2 gesetzt ist.

Es stellt sich heraus, dass n auf 1 gesetzt ist. Warum?

Ich bin zu Fragen, und die Beantwortung meiner eigenen Frage, denn ich möchte die Erklärung für dieses bit von C++ esoterica in Stack-Überlauf. Eine version von diesem Problem heimgesucht hat unser Entwickler-team zweimal, so dass ich vermute, dass diese info von nutzen sein könnten, um jemand da draußen. Bitte schreiben Sie eine Antwort heraus, wenn man erklären kann, ihn in einen anderen/besseren Weg...
Ich Frage mich, warum wurde dies nach unten gestimmt? Als ich zum ersten mal C++ ist dies wirklich verwirrt mich. +1
Was mich wundert, ist das fehlen einer compiler-Warnung. Der compiler ersetzt ein Aufruf an die "definierte Funktion in der Klasse des aktuellen Konstruktor" für das, was in jedem anderen Fall werden die "überschrieben" - Funktion in einer abgeleiteten Klasse. Wenn der compiler sagte, "ersetzt Base::foo() aufrufen, um virtuelle Funktion foo() in Konstruktor" dann der Programmierer würde gewarnt sein, dass der code nicht das tun, was Sie erwartet. Das wäre viel hilfreicher als die silent-substitution, führt zu geheimnisvollen Verhalten, viele debugging, und schließlich eine Reise nach stackoverflow für die Erleuchtung.

InformationsquelleAutor David Coufal | 2009-06-07

Schreibe einen Kommentar