Why does assignment operator call constructor?

天涯浪子 提交于 2021-02-16 15:55:28

问题


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?


回答1:


holder = b attempts to assign from b to Holder. b is of type A*, and holder is of type Holder<A>.

The Holder template defines assignment from another instance of the same Holder type, so the compiler looks for a conversion from A* to Holder<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 explicit keyword.




回答2:


Both the constructor and assignment operator are called. You can check this by printing something in operator =.

This happens because operator = is defined to take a const Holder &, but b is of type A *. So first the Holder(T *) constructor is called to create a temporary object, then this object is assigned to holder through operator =.

If you define an operator =(const T *), only the assignment operator will be called.




回答3:


I do not see a version of the assignment operator that takes a right hand side of A*

    A*        a        = new A(1);
    Holder<A> holder(a);
    A*        b         = new A(2);

    // assigning object of type A* to Holder<A>
    holder = b;

    // No appropriate assignment operator provide.
    // But a constructor is available to convert RHS parameter to correct type.
    // So compiler generates the following code:

    holder = Holder<A>(b);

    // There is an appropriate assignment operator for this.
    // So it compiles. 



回答4:


You have a constructor taking a T* . Your assigment has a rhs pointer ,so it construct a temp-obj with that pointer as argument and assigns this to holder.



来源:https://stackoverflow.com/questions/4383015/why-does-assignment-operator-call-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!