2016-06-28 16 views
9

meinen CodeMitgliedsfunktion nicht vererbt? Dies ist

class B { 
public: 
    virtual void insert(int t, int p) = 0; 

    void insert(int t) { 
    insert(t, 0); 
    } 
}; 

class D : public B { 
public: 
    void insert(int t, int p) { } 

}; 

int main() { 
    D d; 
    d.insert(1); 
} 

, die nicht kompiliert werden. Klar, wenn ich d.B :: insert (1) in main sage, aber warum ist das so falsch wie es ist? Vielen Dank.

+0

Siehe https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule – Oktalist

Antwort

0

Ich bin mir ziemlich sicher, dass es ist, weil Sie die Funktion "einfügen" in D neu definiert haben, die die aufgerufen wird. Die Funktion "Einfügen" in der Klasse "D" benötigt zwei Parameter statt einer. Wenn Sie B. :: insert (1) ausführen, rufen Sie "insert" in B auf.

9

Dies liegt daran, dass in diesem Fall die Basisklassenfunktionen nicht in der Überladungsauflösung enthalten sind. Ähnlich verhält es sich mit Funktionen, die im inneren Gültigkeitsbereich deklariert sind - sie überladen Funktionen, die im äußeren Gültigkeitsbereich deklariert sind, nicht (siehe Beispiele unten). Sie können sich vorstellen, dass der abgeleitete Klassenbereich im Basisklassenbereich verschachtelt ist.

Sobald der Compiler D::insert Kandidat gefunden hat, wird es in der Basisklasse nicht weiter suchen. Wenn es keine D::insert gab, dann wird der Compiler in die Basisklasse nach insert suchen. Sie können dieses Problem beheben, indem insert Funktionsnamen von Basisklasse Einführung mit:

using B::insert; 

dies alle B::insert ladenen Funktionen in abgeleiteten Klasse einführen. Oder wie Sie sagen, können Sie explizit Basisklasse Methode aufrufen mit:

d.B::insert(1) 

Beispielcode, wie Überlastung funktioniert auf die gleiche Art und Weise in einem anderen Zusammenhang:

namespace Outer { 
    void foo(double d) { 
    std::cout << "Outer::foo(double d)\n"; 
    } 
    namespace Inner { 
    //using Outer::foo; // uncomment to see "Outer::foo(double d)" in output 
    void foo(int n) { 
     std::cout << "Inner::foo(int n)\n"; 
    } 
    void callMe() { 
     foo(1.1); 
    } 
    } 
} 

int main() { 
    Outer::Inner::callMe(); // Outputes: Inner::foo(int n) 
} 

oder:

void foo(std::string s) { 
    std::cout << "foo(std::string s)\n"; 
} 

void foo(double d) { 
    std::cout << "foo(double d)\n"; 
} 

void foo(int n) { 
    std::cout << "foo(int n)\n"; 
} 

int main() { 
    void foo(int d); // comment out to see foo(double d) in output 
    foo(1.1); // outputs: "foo(int n)", foo(double d) is hidden 
    //foo("hello"); // ups, it wont compile - name lookup in c++ happens before type checking 
        // commenting out `void foo(int d);` above will fix this. 
} 
Verwandte Themen