Frage

Ich lese die C ++ 0x FAQ von Stroustrup und bekam mit diesem Code stecken. Betrachten Sie den folgenden Code

struct A
{
    void f(double)
    {
        std::cout << "in double" << std::endl;
    }
};

struct B : A
{
    void f(int)
    {
        std::cout << "in int" << std::endl;
    }
};


int main()
{
    A a; a.f(10.10);  // as expected, A.f will get called
    B b; b.f(10.10);  // This calls b.f and we lose the .10 here
    return 0;
}

Mein Verständnis war, wenn ein Typ vererbt wird, sind alle geschützt und öffentliche Mitglieder aus der abgeleiteten Klasse zugänglich sein werden. Aber nach diesem Beispiel sieht es aus wie ich falsch bin. Ich hatte erwartet, die b.f werden Basisklassen rufen f . Ich habe das erwartete Ergebnis durch die abgeleitete Klasse zu ändern wie

struct B : A
{
    using A::f;
    void f(int)
    {
        std::cout << "in int" << std::endl;
    }
};

Fragen

  1. Warum wurde es nicht in dem ersten Code zu arbeiten?
  2. Welche Abschnitt in der C ++ Standard beschreibt alle diese Scoping-Regeln?
War es hilfreich?

Lösung

Der erste Code arbeitet als c ++ ist so konzipiert, arbeiten.

Eine Überlastung Auflösung folgt einem sehr komplizierten Satz von Regeln. Von Stroustrup c ++ Bibel 15.2.2 „[A] mbiguities zwischen den Funktionen von verschiedenen Basisklassen werden nicht anhand von Argumenttypen gelöst werden.“

Er geht auf die Verwendung von „Verwendung“ zu erklären, wie Sie beschrieben haben.

Dies ist eine Design-Entscheidung in der Sprache ist.

Ich neige dazu, das Stroustrup Buch eher als der Standard zu folgen, aber ich bin sicher, dass es dort ist.

[Bearbeiten]

Hier ist sie (von der Norm):

Kapitel 13

Wenn zwei oder mehr verschiedene Erklärungen für einen einzelnen Namen im gleichen Umfang angegeben werden, dieser Name wird gesagt, dass überlastet.

Und dann:

13.2 Erklärung Anpassung

1 Zwei Funktionsdeklarationen mit dem gleichen Namen auf dieselbe Funktion verweisen, wenn sie im gleichen Umfang sind und äquivalente Parameterdeklarationen (13.1). Ein Funktionselement einer abgeleiteten Klasse ist nicht in dem gleichen Umfang als Funktion Mitglied der gleiche Name in einer Basisklasse.

Andere Tipps

Sein, weil A :: f ist „versteckt“ und nicht als „überlastet“ oder „außer Kraft gesetzt“. Siehe:

http://www.parashift.com /c++-faq-lite/strange-inheritance.html#faq-23.9

Suchen Sie nach Überladungsauflösung . Ein ähnliche, aber nicht identische Frage .

In C ++ gibt es keine Überlastung über Bereiche, in abgeleiteten Klassen scoped ist keine Ausnahme. (nach dem C ++ Programming Language)

Für weitere Informationen Besuche http: //www.research. att.com/~bs/bs_faq2.html#overloadderived

Im ersten Fall ist die Basisklassenmethode ‚f‘ versteckt von der abgeleiteten Klasse Methode. In C ++ gibt es keine Überlastung über Bereiche; aus diesem Grund ist es nicht aufgerufen. Die C ++ Standard erläutert alle Mitgliedsnamen Suchregeln in der Abschnitt 10.2 Mitglied Namenssuche [class.member.lookup] . HTH

Die erste Version von Code sollte wirklich B nennen :: f. Sie neu definieren das Symbol "f" in struct "B", so versteckt es die ursprüngliche Symbol "f" von struct "A". Es ist keine Überlastung, wie es scheinen mag.

Jedes Mal, wenn Compiler trifft b.f (), sucht er die "B" Struktur für ein Symbol "f". Es ist dort vorhanden, so dass der Compiler entscheidet, B :: f (int) zu nennen, das Umwandeln doppelt auf Int. Es sieht keine Notwendigkeit, die übergeordnete Klasse für eine geeignete Funktion zum Scannen ...

Doch wenn Sie hinzufügen „mit A :: f“, es ist eine explict Richtlinie für den Compiler eine Elternklasse für Symbol „f“ zu scannen. Nun, B-Klasse verfügt über zwei überladene Funktionen:. Für int und für Doppel

Ich glaube auch, dass Sie B. A schreiben könnten :: f () ohne "using" Direktive in dem ursprünglichen Beispiel mit ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top