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);
в классе "производных".
теперь ваш код будет компилироваться без каких-либо предупреждений.