2016-04-14 4 views
0

Grundsätzlich meine Frage bezieht sich auf Name Lookup und using Deklaration().
Angenommen, haben wir die folgenden (auf jeden Fall dumm) Codes:Auswirkungen der Verwendung der Deklaration auf Name suchen für zwei genau die gleichen Namen

class Base { 
public: 
    void fun() 
    {std::cout << "Base fun" << std::endl;} 
}; 

class Derived : public Base { 
public: 
    // Here both names "fun" are visible or not? 
    using Base::fun;//let's call this func_1 

    void fun() //let's call this func_2 
    { 
     std::cout << "Derived fun" << std::endl; 
    } 
}; 

Derived d; 
d.fun(); // This resolves to func_2, why? 

Deshalb verstehen meine ist jetzt wir beide Namen sichtbar, und dann für Namenssuche haben sollte, sollte es einige Unklarheiten sein. Aber eigentlich ist es nicht. Was ist der Grund oder, mit anderen Worten, verkenne ich einige Konzepte falsch?

+0

einen direkten Link http wäre helfen können: // en. cppreference.com/w/cpp/language/using_declaration – Cubbi

Antwort

3

Der Standard hat eine spezielle Regel für diesen Fall.

Wenn ein Verwendung Deklaration Namen von einer Basisklasse in einer abgeleiteten Klasse Anwendungsbereich bringt Elementfunktionen und Elementfunktion Vorlagen in der abgeleiteten Klasse überschreiben und/oder Ausblenden von Elementfunktionen und Elementfunktion Schablonen mit den gleicher Name, Parametertypliste (8.3.5), cv-qualification und ref-qualifier (falls vorhanden) in einer Basisklasse (anstatt widersprüchlich).

([namespace.udecl]/15)

Beachten Sie, dass wie üblich Sie Base::fun zwingen kann durch d.Base::fun() tun aufgerufen werden.

0

Der Link namespace ‚s ist für Sie verweisen, sollten Sie stattdessen auf die class using-declaration verweisen, wo es heißt:

Wenn bereits die abgeleitete Klasse ein Mitglied mit dem gleichen Namen hat, Parameterliste und Qualifikationen, verbirgt das abgeleitete Klassenmitglied das Element, das von der Basisklasse eingeführt wird, oder überschreibt es (steht nicht in Konflikt mit diesem).

Im Fall Ihres geposteten Code wird void fun() in Base von void fun() in Derived versteckt, also nein, sie nicht beide "sichtbar" sind, es sei denn, Sie ausdrücklich, wenn Sie fun nennen, Beispiel:

class Base { 
    public: 
     void fun() { std::cout << "base" << std::endl; } 
}; 

class Derived : public Base { 
    public: 
     using Base::fun; 
     void fun() { std::cout << "derived" << std::endl; } 
}; 

Derived d; 
d.fun(); // name lookup calls Derived::fun 
d.Base::fun(); // explicitly call Base::fun 

Zusätzlich, da Sie öffentlich aus Base abgeleitet haben, brauchen Sie streng genommen nicht die using Deklaration; Sie würde in dem Fall, dass void fun()protected in Base waren oder Sie private/protected ‚ly aus Base, Beispiel geerbt:

#include <iostream> 

class Base { 
    public: 
     void fun() { std::cout << "base" << std::endl; } 
    protected: 
     void fun2() { std::cout << "base2" << std::endl; } 
}; 

// class default is private 
class Private : Base { 
    public: 
     // fun() won't be accessible since private inheritance and no using 
     // fun2 can now be accessed directly 
     using Base::fun2; 
}; 

class Public : public Base { 
    public: 
     // fun is already public 
     using Base::fun2; // bring into scope 
}; 

class Derived : public Base { 
    public: 
     using Base::fun; 
     using Base::fun2; 

     // overriden method fun, no conflict, choose this method if type is Derived 
     void fun() { std::cout << "derived" << std::endl; } 
}; 

int main(int argc, char* argv[]) 
{ 
    Private p; 
    Public u; 
    Derived d; 

    // generates a compiler error since Base is privately inherited 
    //p.fun(); 
    p.fun2(); // OK, output: base2 

    u.fun(); // OK, output: base 
    u.fun2(); // OK, output: base2 

    // use Derived::fun since override 
    d.fun(); // OK, output: derived 
    d.Base::fun(); // OK, output: base 
    d.fun2(); // OK, output: base2 

    return 0; 
} 

Hoffnung, die

Verwandte Themen