vererbt und überladen



  • Hallo,

    class A
    {
    public:
    	virtual int get(int x)
    	{
    		return get(x, 1);
    	}
    	virtual int get(int x, int y)
    	{
    		return y;
    	}
    };
    
    class B : public A
    {
    public:
    	virtual int get(int x)
    	{
    		return get(x, 2);
    	}
    };
    

    Erwartet hätte ich, dass B::get einfach A::get aufrufen kann. Laut Compiler geht das aber nicht, get(int, int) ist nicht bekannt. An der Stelle könnte ich mir per return A::get(x, 2); behelfen. Was ich als tragischer erachte ist, dass das hier auch nicht mehr geht:

    B *b = new B();
    b->get(2, 3);
    

    Warum wird get(int, int) total ausgeblendet? Beide Funktionen sind ja an sich eigenständige Funktionen in der Klasse und somit unabhängig voneinander?!
    Anschließend hatte ich das ganze in C# getestet und da funktioniert es so wie erwartet.

    Compilerfehler oder Sprachfeature?

    greetz KN4CK3R



  • get(int,int) wird überdeckt (Überdeckung, neben Überladung und Überschreibung). Mit einer using-Deklaration kann die Funktion wieder in den Scope von B aufgenommen werden.

    class B : public A
    {
    public:
        using A::get;
        virtual int get(int x)
        {
            return get(x, 2);
        }
    };
    


  • die erneute definition der Funktion überschreibt den ganzen Namen, unabhängig vom Typ der Funktion.
    (ähnlich wie in:

    int a = 5;
    {
        double a = 1.5;
    }
    

    )

    Du musst folgendes schreiben:

    class B : public A
    {
    public:
        using A::get;
        // ...
    };
    

  • Mod

    Deklarationen in inneren Scopes verdecken Deklarationen gleichen Namens in äußeren Scopes. Basisklassen sind in Hinblick auf die Namensauflösung äußere Scopes. Die Deklaration von get in B verdeckt folglich beide get-Deklarationen aus A. Um auf diese zugreifen zu können, muss ein qualifizierter Bezeichner (also A::get) verwendet werden, oder aber die Deklarationen müssen in der Klasse wiederholt werden (per using).

    B *b = new B();
    b->get(2, 3); // Fehler
    b->A::get(2, 3); //ok
    ((A*)b)->get(2, 3); // ok
    ((A*)b)->A::get(2, 3); // nat. auch ok
    


  • ah sehr gut, meine Rettung 😃 danke euch

    greetz KN4CK3R


Anmelden zum Antworten