2

为什么这不编译?
错误 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

4 回答 4

8

一旦你声明了一个函数:

void WriteLine()

在派生类中,它隐藏了所有具有相同名称的基类函数。
上述不带参数的函数隐藏了同名带一个参数的函数,由于编译器找不到一个带一个参数的函数,所以会报错。

该行:

using AbstractBase::WriteLine;

在派生类中启用(引入范围)来自基类的所有隐藏名称,因此采用一个参数的函数可用。

好读:
什么意思,警告:Derived::f(char) 隐藏 Base::f(double)?

于 2012-06-18T15:42:31.243 回答
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;
   }
};
于 2012-06-18T15:42:04.513 回答
1

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

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

于 2012-06-18T15:42:14.393 回答
1

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

using AbstractBase::WriteLine;

到你的派生类。

于 2012-06-18T15:42:35.483 回答