C ++纯虚函数继承(相同签名)

时间:2012-06-18 15:40:07

标签: c++ inheritance method-signature

为什么不编译?
错误C2660:'Concrete :: WriteLine':函数不带1个参数
我知道如果我添加线:
//使用AbstractBase :: WriteLine;
它有效,但我不明白为什么。

#include "iostream" 

class AbstractBase
{
public:
   virtual void WriteLine() = 0;
   virtual void WriteLine( int i )
   {
      std::cout<<"AbstractBase"<<std::endl;
   }
};

class Concrete : public AbstractBase
{
public:
   //using AbstractBase::WriteLine;
   virtual void WriteLine()
   {
      std::cout<<"Concrete Sub Class"<<std::endl;
   }
};

int main()
{
   Concrete ff;
   ff.WriteLine();
   ff.WriteLine(1);
   return 0;
}

有人可以解释一下这里发生了什么。 感谢名单


有没有人知道这种行为是否是来自C ++标准的已定义行为。 是否在C ++标准中提到过? 或者它只是一种编译器行为?

4 个答案:

答案 0 :(得分:8)

声明一个函数后:

void WriteLine()

在派生类中, 隐藏 所有具有相同名称的基类函数。
上面没有参数的函数隐藏了具有相同名称的函数并且接受了一个参数,由于编译器找不到具有一个参数的函数,因此报告错误。

该行:

using AbstractBase::WriteLine;

启用(引入范围)派生类中Base类的所有隐藏名称,因此可以使用带有一个参数的函数。

好读:
What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?

答案 1 :(得分:2)

隐藏方法。基类中的另一个函数被具有相同名称的函数隐藏,尽管它具有不同的签名。

要解决此问题,您可以使用using指令:

using AbstractBase::WriteLine;

在派生类中:

class Concrete : public AbstractBase
{
public:
   using AbstractBase::WriteLine;
   //using AbstractBase::WriteLine;
   virtual void WriteLine()
   {
      std::cout<<"Concrete Sub Class"<<std::endl;
   }
};

答案 2 :(得分:1)

在派生类中声明函数会隐藏基类中具有相同名称的所有函数 - 它们不会被视为派生类函数的潜在重载。

添加using声明会将隐藏的函数带回到派生类的范围内,并且它们与派生类函数一起被视为潜在的重载。

答案 3 :(得分:1)

问题是Concrete::WriteLine隐藏了所有AbstractBase::WriteLines。你可以添加

using AbstractBase::WriteLine;

到派生类。