Ответ 1
Вы не можете сделать это напрямую. Подумайте об этом случае:
Base b;
Derived d;
Base& d_ref = d;
d_ref.seriousMethod(b); // What happens here?
В момент компиляции переменная d_ref
имеет статический тип Base
, поэтому в соответствии с определением Base
он должен иметь возможность принимать b
в качестве параметра seriousMethod
.
Но во время выполнения динамический тип d_ref
равен Derived
, поэтому в соответствии с определением Derived
он не может принимать b
в качестве параметра seriousMethod
. Он не может преобразовать b
в Dervied
, поскольку это может быть прямой объект Base
(если Base
не является абстрактным), или может быть какой-то другой класс, полученный из Base
, который не является таким же, как Derived
.
Вы правы, полагая, что единственный реальный способ сделать это - любопытно повторяющийся шаблон шаблона, т.е. шаблон Base
и определение Dervied
как:
class Derived : public Base<Derived> { ... }
Это устраняет проблему, проиллюстрированную выше, потому что каждый тип, полученный из Base<T>
, будет иметь отдельный базовый класс и не будет связан между собой через наследование.