2017-02-14 12 views
0

В следующем кодеЧастная виртуальная функция базы скрыта частной виртуальной функции производного

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; 
} 

скомпилирован с g++ -Woverloaded-virtual производит сказал предупреждение:

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 {} 
    ^

Я не понимаю, что в настоящее время скрывается здесь. Из области C существует только одна возможная перегрузка до f, так как B::f(int) является закрытой в пределах C.

Из области B есть два, но оба они явно указаны внутри B.

ответ

1

Цитируя GCC manual:

-Woverloaded-virtual (С ++ и Objective-C++, только) Предупреждать при объявлении функции скрывает виртуальные функции от базового класса. Так, например, в:

struct A { 
    virtual void f(); 
}; 

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

версия A класса f скрыта в B, и код, как:

B* b; 
b->f(); 

не удается собрать.

4

Предупреждение говорит вам, что функция C::f(float) скрывает B::f(int), и это потому, что it does. Спецификаторы доступа не влияют на перегрузку, поэтому факт, что B::f(int) является закрытым, не имеет значения. Даже если B::f(int) был общедоступным, он не будет учитываться при разрешении перегрузки, и это то, на что ссылается «скрытие».

+0

Но в чем же смысл этого предупреждения? Он предупреждает меня о чем-то, что на самом деле не относится к моей ситуации. Как я могу избавиться от него (кроме переключателя '#pragma diagnostics')? – TFM

+0

@TFM, 'C * c = new C; c-> f (int {}); здесь f (float) будет выбран для диспетчеризации. но здесь 'B * b = c; b -> f (int {}) 'f означает f (int). например, если у вас есть следующая иерархия 'struct A {virtual void f (int), f (float); }; struct B: A {void f (float);}; struct C: B {void f (int), f (float);}; ", то через if if вы можете отправить только f (float), если вы явно не квалифицируете имя f с помощью A (b_iface-> A :: f (int {})). –

+0

@ GreenTree Я понимаю, что означает это предупреждение в ситуации, в которой оно действительно имеет смысл. Я пытаюсь понять его последствия в моей ситуации. – TFM

1

Я не понимаю, что скрывается здесь. Из области C существует только одна возможная перегрузка до f, так как B::f(int) - private в пределах C.

Поиск и разрешение имен происходит до того, как применяются правила доступа.

B::f(int) скрыт C::f(float), когда имя f снято с C. Об этом предупреждает компилятор.

 Смежные вопросы

  • Нет связанных вопросов^_^