Чистое виртуальное наследование 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;
к вашему производному классу.