I
class Top { };
class Middle: public Top{ };
class Bottom: public Middle { };
Top *pt1 = new Middle;
Top *pt2 = new Bottom;
const Top *pt2 = pt1;
tmplate<typename T>
class SmartPtr {
public:
explicit SmartPtr(T* realPtr);
};
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle);
There is no inherent relationship among different instantiations of the same template, so compilers view SmartPtr<Middlet> and SmartPtr<Top> as completely different classes.
template<typename T>
class SmartPtr {
public:
template<typename U>
SmartPtr(const SmartPtr<U>& other);
};
we want to be able to create a SmartPtr<Top> from a SmartPtr<Bottom>, but we do not want to be able to create a SmartPtr<Bottom> from a SmartPtr<Top>, as that’s contray to the meaning of public inheritance.
I.I
template<typename T>
class SmartPtr{
public:
template<typename U>
SmartPtr(const SmartPtr<U>& other): heldPtr(other.get()) { }
T* get() const { return heldPtr; };
private:
T* heldPtr;
};
heldPtr(other.get()) this will compile only if there is an impilcit conversion from a U* pointer to a T* pointer, and that is precisely what we want.
II.
Declaring a generalized copy constrctor (a member template) in a class doesn’t keeep compilers from generating their own copy constructor, so if you want to control all aspects of copy construction, you must declare both a generalized copy constructor as well as the “normal” copy constructor.
template<typename T> clas shared_ptr {
public:
// copy constructor
shared_ptr(shared_ptr const& r);
// generalized copy constructor
template<typename Y>
shared_ptr(shared_ptr<Y> const& r);
// copy assignment
shared_ptr& operator=(shared_ptr const& r);
// generalized copy assignment
template<class Y>
shared_ptr& operator = (shared_ptr<Y> const& r);
};