The following C++ code i think is correct, but produce some warnings when compiled with "-Woverloaded-virtual", is the warning bogus or there is a real problem with this code?
If that is a bogus warning what can i do to avoid it, define all the exception virtual variants in derived get rids of the warning but maybe is a better solution
G++ command:
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++ code
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");
}
};
The warning means that:
When you are not using dynamic dispatch then your derived
class object can only call,
void exception()
and it will hide all same named methods of the Base class intermediate
.
In order that your derived class object can call all the same named methods in base class intermediate
, You need to add the following line to your derived
class.
using intermediate::exception;
Ofcourse, You are in best position to decide if this is a problem or not.
The warning is due to the fact that you cannot call derived::exception(const char*)
on an object of type derived
(or through a pointer to derived
), even though the parent class defines it and it is virtual (so you would expect it to be available in derived
). To remove the warning, you need to expose that member function in derived
:
class derived : public intermediate
{
public:
virtual void exception(const char* msg) {intermediate::exception(msg);}
virtual void exception()
{
intermediate::exception("derived:unknown exception");
}
};
Or if you do not want to expose it to others, declare it as private with no defintion.
class derived : public intermediate
{
public:
virtual void exception()
{
intermediate::exception("derived:unknown exception");
}
private:
void exception(const char* tmp);
};
UPDATE: After double-checking (and as pointed out by Als) the using directive, you could do this too:
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");
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With