Чистое виртуальное наследование C++ (та же сигнатура)

Почему это не компилируется?
ошибка 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;
}

Может кто-нибудь объяснить мне, что здесь происходит. Thanx


Кто-нибудь знает, является ли это поведение определенным поведением в стандарте C++. Это упомянуто в стандарте C++? Или это просто своего рода поведение компилятора?

4 ответа

Решение

Как только вы объявите функцию:

void WriteLine()

в производном классе он скрывает все функции базового класса с одинаковыми именами.
Приведенная выше функция, которая не принимает параметров, скрывает функцию с тем же именем и одним параметром, так как компилятор не может найти функцию с одним параметром и сообщает об ошибке.

Линия:

using AbstractBase::WriteLine;

включает (вводит в область действия) все скрытые имена из базового класса в вашем производном классе, и, следовательно, доступна функция, принимающая один параметр.

Хорошо для чтения:
В чем смысл, Предупреждение: Derived:: f (char) скрывает Base::f(double)?

Метод сокрытия бывает. Другая функция в базовом классе скрыта функцией с тем же именем, хотя и имеет другую подпись.

Чтобы решить эту проблему, вы можете использовать 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;
   }
};

Объявление функции в производном классе скрывает все функции с одинаковыми именами в базовом классе - они не рассматриваются как потенциальные перегрузки функций производного класса.

Добавление using Объявление возвращает скрытые функции обратно в область производного класса, и они рассматриваются как потенциальные перегрузки вместе с функциями производного класса.

Проблема в том, что Concrete::WriteLine скрывает все AbstractBase::WriteLines, Можете добавить

using AbstractBase::WriteLine;

к вашему производному классу.

Другие вопросы по тегам