2016-06-25 8 views
1

Ich möchte eine Funktion in einer abstrakten Klasse definieren, die eine abstrakte (virtuelle) Funktion aufruft. Aber wenn ich von der abstrakten Klasse erbte, wird diese Funktion nicht vererbt:So rufen Sie eine abstrakte Funktion mit einer abstrakten Klasse

class A { 
public: 
    virtual void f(int t) = 0; 

    void f() { 
     f(0); 
    } 
}; 

class B : public A { 
public: 
    void f(int t) override { } 

    // using A::f; // uncomment to fix the problem 
}; 

int main() { 
    B b; 
    b.f(0); // works 
    b.f(); // error: no matching function for call to ‘B::f()’ 
} 

Warum funktioniert das nicht? Die Problemumgehung besteht darin, using A::f zu verwenden, aber warum wird A::f() nicht vererbt?

+1

'A :: f' * ist * geerbt, aber es wird durch' B :: f (int) 'versteckt. Die Namenssuche wird beendet, wenn der Name gefunden wird. Ob Argumente übereinstimmen oder nicht, ist an dieser Stelle nicht relevant. Klareres Beispiel: Wenn 'B' eine Elementvariable mit dem Namen' f' und nicht eine Elementfunktion definiert, wird auch 'A :: f' nicht gefunden. Wenn Sie 'b.A :: f()' anstelle von 'b.f()' schreiben, kompiliert Ihr Programm. – JohnB

Antwort

2

Es funktioniert nicht, weil B keine f() hat, nur eine f(int).

Wenn B keine Funktion namens f hatte, dann würde die Superklasse nach einer passenden Funktion mit Überladungsauflösung gesucht werden. Aber da die Unterklasse B bereits eine Funktion namens f hat, wird die Oberklasse nicht durchsucht, und die Überladungsauflösung erfolgt in B.

Dies ist, was das Schlüsselwort using ist, um die Superklasse f() ein Teil B Namespace zu machen. Die Antwort hier ist wirklich, "weil C++ so funktioniert".