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