gcc Woverloaded虚拟警告

gcc Woverloaded-virtual warnings

本文关键字:警告 虚拟 Woverloaded gcc      更新时间:2023-10-16

下面的C++代码我认为是正确的,但在使用"-Woverloaded virtual"编译时会产生一些警告,警告是假的还是这个代码有真正的问题?

如果这是一个虚假的警告,我能做些什么来避免它,在派生的警告中定义所有异常虚拟变体,但这可能是一个更好的解决方案

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");
    }
};

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

 void exception()     

并且它将隐藏基类CCD_ 2的所有相同命名的方法。

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

 using intermediate::exception;

当然,你处于决定这是否是一个问题的最佳位置。

此警告是由于您不能在类型为derived的对象上调用derived::exception(const char*)(或通过指向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);
}; 

更新:在仔细检查(正如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);

现在,您的代码将在没有任何警告的情况下编译。