Есть вот такая реализация shared_ptr.
Далее, где-то в клиентском коде есть иерархия классов с родителем:
class Creature {
public:
virtual void eat(shared_ptr<Fruit> f) = 0;
};
Теперь, хочется иметь возможность сделать:
class Apple : public Fruit {
...
public:
void appleSpecificMethod();
};
...
shared_ptr<Apple> pApple = new Apple;
pApple->appleSpecificMethod();
someCreature->eat(pApple); // иметь возможность передавать shared_ptr<производный_от_Fruit_класс> в eat(shared_ptr<Fruit>)
Для этого я добавляю в shared_ptr шаблонный конструктор:
template<class T> template <class Y>
inline shared_ptr<T>::shared_ptr(const shared_ptr<Y> &y) {
attachStorage(y.getStoragePtr());
}
и
template<class T> template<class Y>
inline void shared_ptr<T>::attachStorage(shared_ptr_storage<Y> *pStorage) {
// Вопрос:
// Как правильно сделать проверку валидности преобразования Y* к T* во время компиляции?
// Ничего кроме этого в голову не приходит:
// {
// Y *pY = NULL;
// T *pT = pY;
// }
myStorage = reinterpret_cast<shared_ptr_storage<T>*>(pStorage);
if (myStorage != 0) {
myStorage->addReference();
}
}