I am just playing around to understand smart pointers and trying to make mine but I come across a situation that I do not fully understand. Here is the code:
#include <iostream>
template <class T>
class Holder
{
private:
T * obj;
public:
Holder(T * tt) : obj(tt)
{
std::cout << "ctor : " << tt->dummy << std::endl;
}
T * operator -> ()
{
return obj;
}
operator bool()
{
return obj;
}
T * const get() const
{
return obj;
}
void reset() {swap(0);}
void swap(T * other)
{
obj = other;
}
Holder & operator = (const Holder& holder)
{
obj = holder.get();
return *this;
}
Holder(const Holder & holder) : obj(holder.get()) {}
};
class A
{
public:
int dummy;
A(int a) : dummy(a) {}
};
int main ()
{
A * a = new A(1);
Holder<A> holder(a);
A * b = new A(2);
holder = b;
std::cout << holder->dummy << std::endl;
return 0;
}
The code compiles and on the line of holder = b; the constructor of Holder class is called. I thought compiler would give an error. It is not the assingment operator but why is it calling constructor?
holder = battempts to assign frombtoHolder.bis of typeA*, andholderis of typeHolder<A>.The
Holdertemplate defines assignment from another instance of the sameHoldertype, so the compiler looks for a conversion fromA*toHolder<A>. It finds the constructor, and uses that.Constructors which may take exactly one argument may be used for implicit conversions, unless you tag them with the
explicitkeyword.