gcc Woverloaded-виртуальные предупреждения

следующий код C++, который я считаю правильным, но выдает некоторые предупреждения при компиляции с "-Woverloaded-virtual", является ли предупреждение фиктивным или есть реальная проблема с этим кодом?

Если это фиктивное предупреждение, что я могу сделать, чтобы избежать этого, определите все виртуальные варианты исключений в производных get rids предупреждения, но, возможно, это лучшее решение

команды G++:

   g++ -c -Woverloaded-virtual test.cpp 
test.cpp:22:18: warning: ‘virtual void intermediate::exception(const char*)’ was hidden [-Woverloaded-virtual]
test.cpp:32:18: warning:   by ‘virtual void derived::exception()’ [-Woverloaded-virtual]

код C++

using namespace std;

class base
{
public:

    virtual void exception() = 0;
    virtual void exception(const char*) = 0;
};

class intermediate : public base
{
public:

    virtual void exception()
    {
    cerr << "unknown exception" << endl;
    }

    virtual void exception(const char* msg)
    {
    cerr << "exception: " << msg << endl;
    }
};

class derived : public intermediate
{
public:

    virtual void exception() 
    { 
        intermediate::exception("derived:unknown exception");
    }
};

3 ответов


предупреждение означает, что:
Когда вы не используете динамическую отправку, тогда ваш derived объект класса можно вызывать только

 void exception()     

и он скроет все те же именованные методы базового класса intermediate.

для того, чтобы ваш объект производного класса мог вызывать все те же именованные методы в базовом классе intermediate, вам нужно добавить следующую строку в свой derived класса.

 using intermediate::exception;

конечно, вы находитесь в лучшем положении, чтобы решить, если это проблема или нет.


предупреждение связано с тем, что вы не можете позвонить derived::exception(const char*) на объект типа derived (или через указатель на derived), хотя родительский класс определяет его, и он является виртуальным (поэтому вы ожидаете, что он будет доступен в derived). Чтобы удалить предупреждение, необходимо предоставить эту функцию-член в derived:

class derived : public intermediate 
{ 
public: 
  virtual void exception(const char* msg) {intermediate::exception(msg);}
  virtual void exception()  
  {  
    intermediate::exception("derived:unknown exception"); 
  } 
}; 

или если вы не хотите подвергать его воздействию других, объявите его частным без определения.

class derived : public intermediate 
{ 
public: 
  virtual void exception()  
  {  
    intermediate::exception("derived:unknown exception"); 
  } 
private:
  void exception(const char* tmp);
}; 

UPDATE: после двойной проверки (и, как указано Als) директива using, вы также можете сделать это:

class derived : public intermediate 
{ 
public: 
  using intermediate::exception; // imports both declarations from intermediate
  virtual void exception() // will not clash with the imported declaration of the
                           // same signature, but properly overriders the parent
                           // class's defition
  {  
    intermediate::exception("derived:unknown exception"); 
  } 
}; 

пожалуйста, переопределите функцию:

virtual void exception(const char* msg); в классе "производных".

теперь ваш код будет компилироваться без каких-либо предупреждений.