Why do classes like shared_ptr have another template in their constructors?
For example:
template<class T> class shared_ptr {
public:
  template<class Y>
  explicit shared_ptr(Y * p);
I've been reading Scott Meyers's Effective C++, item 45, which says the idea behind it is to make polymorphism possible through them; that is, construct shared_ptr<A> from shared_ptr<B> if B is derived from A.
But isn't defining a constructor like
explicit shared_ptr(T * p);
enough? I mean, this code works just fine:
class C1 {
};
class C2 : public C1 {
};
template<typename T>
class A
{
public:
  A(T &a)
  {
    var1 = a;
  }
  T var1;
};
int main(int argc, char *argv[])
{
  C2 c2;
  A<C1> inst1(c2);
}
So why do we need another template for constructor there?
Copy Constructor is of two types:Default Copy constructor: The compiler defines the default copy constructor. If the user defines no copy constructor, compiler supplies its constructor. User Defined constructor: The programmer defines the user-defined constructor.
Copy Constructor in C++ A copy constructor is a member function that initializes an object using another object of the same class. A copy constructor has the following general function prototype: ClassName (const ClassName &old_obj);
A class can have multiple copy constructors, e.g. both T::T(const T&) and T::T(T&). If some user-defined copy constructors are present, the user may still force the generation of the implicitly declared copy constructor with the keyword default .
Hence, there is always one copy constructor that is either defined by the user or by the system.
Without the template constructor, the following code would have undefined behavior:
#include <memory>
class Base {};
class Derived : public Base {};
int main() {
    std::shared_ptr<Base> ptr( new Derived );
}
If shared_ptr takes only a Base*, it is forced to eventually call delete on that Base* pointer.  But since Base does not have a virtual destructor and the pointer actually points at Derived, this is undefined behavior.
But in reality, the code above is well-formed.  The template constructor for shared_ptr takes a Derived* pointer and stores a custom deleter that calls delete on the original Derived* pointer, which is fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With