gcc Woverloaded-virtual warnings

Jos*_*osé 18 c++ gcc virtual-functions overloading

我认为以下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]
Run Code Online (Sandbox Code Playgroud)

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");
    }
};
Run Code Online (Sandbox Code Playgroud)

Alo*_*ave 22

警告意味着:
当您不使用动态调度时,您的derived类对象只能调用,

 void exception()     
Run Code Online (Sandbox Code Playgroud)

它将隐藏Base类的所有相同命名方法intermediate.

为了使派生类对象可以在基类中调用所有相同的命名方法intermediate,您需要在类中添加以下行derived.

 using intermediate::exception;
Run Code Online (Sandbox Code Playgroud)

当然,您最有可能决定这是否是一个问题.


Att*_*ila 14

警告是由于您无法调用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"); 
  } 
}; 
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想将其公开给其他人,请将其声明为私有,没有明确规定.

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

更新:在仔细检查(和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"); 
  } 
}; 
Run Code Online (Sandbox Code Playgroud)