Например, у меня есть базовый класс с чисто виртуальными функциями:
class IBase
{
virtual void Function(const IBase& ref) = 0;
};
Если я наследую класс, нужно ли перегружать функцию, которая принимает производный класс в качестве параметра?
class Derived
{
// this will be implemented
virtual void Function(const IBase& ref) {}
// does this have to be implemented
virtual void Function(const Derived& ref) {}
};
Или компилятор может различать вызовы, и я могу пропустить написание функции перегрузки?
Derived d();
...
IBase* dptr = &d; // ignoring cast for example
// would never really call 'Function' on itself, this is for example purposes
dptr->Function(d);
Примечания: IBase :: Function должен принимать ссылочный тип, а не тип указателя.
Я понимаю правила наследования чисто виртуальных функций, но не в этом особом случае, когда чисто виртуальная функция принимает базовый тип в качестве параметра.
Что мне нужно знать, так это то, должен ли я реализовывать перегрузку в каждом унаследованном типе, который принимает унаследованный тип в качестве параметра, или компилятор поймет, что если я передам ссылку Derived, чтобы вызвать виртуальную реализацию?
Да, если у вас есть Function(const IBase&)
в базовом классе и переопределить его в производном классе, вы можете передать ссылки на производный класс Function
и Function(const IBase&)
будет называться.
Что мне нужно знать, так это то, должен ли я реализовывать перегрузку в каждом унаследованном типе, который принимает унаследованный тип в качестве параметра, или компилятор поймет, что если я передам ссылку Derived, чтобы вызвать виртуальную реализацию?
Если вы переопределяете только функцию, определенную в базовом типе, и не добавляете перегрузку, компилятор преобразует все экземпляры Derived
в IBase
и вызвать существующую функцию.