Gcc Woverloaded-virtual warnings
Следующий код на С++, который, по моему мнению, верен, но выдает некоторые предупреждения при компиляции с помощью "-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]
Код С++
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");
}
};
Ответы
Ответ 1
Предупреждение означает, что:
Когда вы не используете динамическую отправку, ваш объект класса derived
может вызывать только
void exception()
и он скроет все одинаковые именованные методы базового класса intermediate
.
Чтобы ваш объект производного класса мог вызывать все одинаковые именованные методы в базовом классе intermediate
, вам нужно добавить следующую строку в класс derived
.
using intermediate::exception;
Конечно, вы в лучшем положении, чтобы решить, является ли это проблемой или нет.
Ответ 2
Предупреждение связано с тем, что вы не можете вызвать 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 defition
{
intermediate::exception("derived:unknown exception");
}
};
Ответ 3
Пожалуйста, переопределите функцию:
virtual void exception(const char* msg);
в классе "производный".
Теперь ваш код будет компилироваться без каких-либо предупреждений.