(Я поместил некоторый код на ideone (Отредактировано, чтобы иметь некоторые виртуальные деструкторы. Это важно для того, чтобы shared_ptr правильно уничтожал DoublyDerived2 в примере.))
На основе комментариев квопрос, я думаю, что конечной целью является, чтобы конструктор Derived1 каким-то образом «знал» и «запоминал» тип static объекта, переданного в конструктор Derived1.В частности:
Derived2<string> *p = new DoublyDerived2<string>();
// static type of p is Derived2, not DoublyDerived
shared_ptr<Base1> x = something_that_creates_a_Derived1(p);
Объект Derived1 должен знать, что p
имеет тип Derived2, а не просто имеет тип Base2
Предполагая, что это правильное понимание проблемы, этот код на ideoneдолжен решить это.Основная хитрость заключается в том, что make_Derived1 является шаблоном, а выведенный тип используется при создании Derived1.Derived1 сам по себе является шаблоном, который гарантирует, что его метод foo
знает тип.
template <class T>
shared_ptr<Base1> make_Derived1(shared_ptr<T> ptr) {
cout << typeid(ptr).name() << endl;
return shared_ptr<Base1>(new Derived1<T>(ptr));
}
и использование:
int main() {
shared_ptr< Derived2<string> > p ( new DoublyDerived2<string>() ) ;
shared_ptr<Base1> x = make_Derived1(p);
x->f(); // prints something like "Derived2", as desired.
}