2017-02-14 3 views
0

den folgenden Codeprivate virtuelle Funktion der Basis von privaten virtuellen Funktion abgeleitet

class A 
{ 
public: 
    void g(int x) 
    { 
     f(x); 
    } 

protected: 
    virtual void f(int) = 0; 
}; 

class B: public A 
{ 
protected: 
    virtual void f(float) = 0; 

private: 
    void f(int x) override final 
    { 
     f(float(x)); 
    } 
}; 

class C: public B 
{ 
private: 
    void f(float) override final {} 
}; 

int 
main() 
{ 
    C c; 
    c.g(1); 

    return 0; 
} 

zusammengestellt mit g++ -Woverloaded-virtual versteckt wird, erzeugt die Warnung:

x.cc:19:7: warning: ‘virtual void B::f(int)’ was hidden [-Woverloaded-virtual] 
    void f(int x) override final 
    ^
x.cc:28:7: warning: by ‘virtual void C::f(float)’ [-Woverloaded-virtual] 
    void f(float) override final {} 
    ^

Ich verstehe nicht, was hier versteckt wird. Aus dem Gültigkeitsbereich C gibt es nur eine mögliche Überlast auf f, da B::f(int) innerhalb C privat ist.

Aus dem Bereich B gibt es zwei, aber beide sind explizit innerhalb B benannt.

Antwort

1

Zitiert die GCC manual:

-Woverloaded-virtual (C++ und Objective-C++ nur) Warnen, wenn eine Funktionsdeklaration virtuelle Funktionen von einer Basisklasse verbirgt. Zum Beispiel in:

struct A { 
    virtual void f(); 
}; 

struct B: public A { 
    void f(int); 
}; 

die A Klasse Version von f ist in B versteckt und Code wie:

B* b; 
b->f(); 

nicht zu kompilieren.

4

Die Warnung Sie sagt, dass die Funktion C::f(float) versteckt B::f(int), und das ist, weil it does. Access-Bezeichner haben keinen Einfluss auf das Überladen, so dass die Tatsache, dass B::f(int) privat ist, keine Rolle spielt. Auch wenn B::f(int) öffentlich ist, würde es nicht für eine Überladungsauflösung in Betracht gezogen werden, und darauf bezieht sich "Verstecken".

+0

Aber was ist der Sinn dieser Warnung? Es warnt mich vor etwas, das in der Tat nicht auf meine Situation zutrifft. Wie kann ich es loswerden (anders als '#pragma diagnostics' Schalter)? – TFM

+0

@TFM, 'C * c = neues C; c-> f (int {}); 'hier wird f (float) zum Versenden ausgewählt. aber hier 'B * b = c; b -> f (int {}) 'f bedeutet f (int). Zum Beispiel, wenn Sie folgende Hierarchie haben: struct A {virtual void f (int), f (float); }; Struktur B: A {void f (float);}; struct C: B {void f (int), f (float);}; 'dann kannst du über Bs iface nur f (float) senden, außer du legst den Namen von f explizit mit A 's fest (b_iface-> A :: f (int {})). –

+0

@GreenTree Ich verstehe, was diese Warnung in einer Situation bedeutet, in der es tatsächlich Sinn macht. Ich versuche seine Auswirkungen in meiner Situation zu verstehen. – TFM

1

Ich verstehe nicht, was hier versteckt wird. Aus dem Umfang C gibt es nur eine mögliche Überlastung zu f als B::f(int) ist private innerhalb C.

Die Suche nach Namen und Auflösung erfolgt, bevor Zugriffsregeln angewendet werden.

B::f(int) wird durch C::f(float) versteckt, wenn der Name f aus einem C Objekt nachgeschlagen. Darüber warnt der Compiler Sie.

Verwandte Themen