Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc Woverloaded-virtual warnings

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");
    }
};
like image 739
José Avatar asked Apr 03 '12 14:04

José


2 Answers

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.

like image 63
Alok Save Avatar answered Oct 21 '22 04:10

Alok Save


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"); 
  } 
}; 
like image 34
Attila Avatar answered Oct 21 '22 02:10

Attila