constructor conversion vs operator =

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • vairavans@gmail.com

    #1

    constructor conversion vs operator =

    Hi Everyone,

    I have the following code,

    class B
    {
    };

    class A
    {
    public: A()
    {
    }
    A(B& ref_obj)
    {
    printf("convers ion\n");
    }
    ~A()
    {
    }
    A operator=(const B& ref)
    {
    printf("operato r\n");
    return A();
    }
    };

    int main()
    {
    A obj;
    B obj1;
    obj = obj1; // invokes the operator=
    A obj2 = obj1 // invokes the constructor conversion
    obj2 = obj1 // invokes the constructor conversion, when
    the operator= function is commented out
    return(0);
    }

    What does the standard say about this? invoking a constructor when the
    object on lvalue is already created...
  • Ondra Holub

    #2
    Re: constructor conversion vs operator =

    On 11 Pro, 17:45, vairav...@gmail .com wrote:
    Hi Everyone,
    >
    I have the following code,
    >
    class B
    {
    >
    };
    >
    class A
    {
    public: A()
    {
    }
    A(B& ref_obj)
    {
    printf("convers ion\n");
    }
    ~A()
    {
    }
    A operator=(const B& ref)
    {
    printf("operato r\n");
    return A();
    }
    >
    };
    >
    int main()
    {
    A obj;
    B obj1;
    obj = obj1; // invokes the operator=
    A obj2 = obj1 // invokes the constructor conversion
    obj2 = obj1 // invokes the constructor conversion, when
    the operator= function is commented out
    return(0);
    >
    }
    >
    What does the standard say about this? invoking a constructor when the
    object on lvalue is already created...
    I think when you comment-out you own definition of operator=, the
    default operator= is used. But the default one needs as parameter
    const A&, so compiler creates it with constructor A(B&). There is no
    other way how to compile it.

    Comment

    • siddhu

      #3
      Re: constructor conversion vs operator =

      On Dec 11, 11:45 am, vairav...@gmail .com wrote:
      Hi Everyone,
      >
      I have the following code,
      >
      class B
      {
      >
      };
      >
      class A
      {
      public: A()
      {
      }
      A(B& ref_obj)
      {
      printf("convers ion\n");
      }
      ~A()
      {
      }
      A operator=(const B& ref)
      {
      printf("operato r\n");
      return A();
      }
      >
      };
      >
      int main()
      {
      A obj;
      B obj1;
      obj = obj1; // invokes the operator=
      A obj2 = obj1 // invokes the constructor conversion
      obj2 = obj1 // invokes the constructor conversion, when
      the operator= function is commented out
      obj1 gets converted to a temporary A's object using constructor
      conversion, then default assignment operator(provid ed by the compiler)
      is getting called.
      return(0);
      >
      }
      >
      What does the standard say about this? invoking a constructor when the
      object on lvalue is already created...

      Comment

      • Abhishek Padmanabh

        #4
        Re: constructor conversion vs operator =

        On Dec 11, 9:45 pm, vairav...@gmail .com wrote:
        Hi Everyone,
        >
        I have the following code,
        >
        class B
        {
        >
        };
        >
        class A
        {
        public: A()
        {
        }
        A(B& ref_obj)
        {
        printf("convers ion\n");
        }
        ~A()
        {
        }
        A operator=(const B& ref)
        {
        printf("operato r\n");
        return A();
        }
        >
        };
        >
        int main()
        {
        A obj;
        B obj1;
        obj = obj1; // invokes the operator=
        A obj2 = obj1 // invokes the constructor conversion
        obj2 = obj1 // invokes the constructor conversion, when
        the operator= function is commented out
        return(0);
        >
        }
        >
        What does the standard say about this? invoking a constructor when the
        object on lvalue is already created...
        The conversion constructor is called to create a temporary object of A
        to use with the compiler generated assignment operator. Try changing
        operator= from this:

        A operator=(const B& ref)
        {
        printf("operato r\n");
        return A();
        }

        to this:

        A operator=(/* const */ A& ref)
        {
        printf("operato r\n");
        return A();
        }

        and see if it compiles (it shouldn't as temporaries cannot be bound to
        reference to non-const). You could easily see all this by writing few
        lines of code in place of compiler generated default members with a
        bunch of std::cout statements.

        Comment

        • Juha Nieminen

          #5
          Re: constructor conversion vs operator =

          vairavans@gmail .com wrote:
          A operator=(const B& ref)
          {
          printf("operato r\n");
          return A();
          }
          operator= should return a reference to "*this", not a new instance.
          Else it doesn't make sense to return anything at all.

          The semantics of '=' is that it's an expression which value is the
          assigned value. If you return a new instance of A you are breaking
          this semantic and thus returning anything at all makes no sense.(The
          most typical case where this property is used is in expressions like
          "a = b = c;" but there are other situations where the property can be
          used as well.)

          If you don't care about the return value of operator=, then it would
          be cleaner to return void.

          Comment

          • James Kanze

            #6
            Re: constructor conversion vs operator =

            On Dec 11, 5:45 pm, vairav...@gmail .com wrote:
            I have the following code,
            class B
            {
            };
            class A
            {
            public: A()
            {
            }
            A(B& ref_obj)
            {
            printf("convers ion\n");
            }
            ~A()
            {
            }
            A operator=(const B& ref)
            {
            printf("operato r\n");
            return A();
            }
            };
            int main()
            {
            A obj;
            B obj1;
            obj = obj1; // invokes the operator=
            What else should it do?
            A obj2 = obj1 // invokes the constructor conversion
            And maybe the copy constructor (which you've not instrumented).
            The semantics of this statement are to convert the
            initialization expression (here "obj1") to the target type (A),
            then initialize the target object using the copy constructor.
            The compiler is explicitly allowed to elide the copy, however,
            as long as there is an accessible copy constructor. (And since
            you don't declare one, the compiler provides one by default.)
            obj2 = obj1 // invokes the constructor conversion, when
            the operator= function is commented out
            If your assignment operator is commented out, the compiler only
            has the copy assignment operator that it implicitly generates to
            work with. This one takes an A const& as argument, which means
            that the compiler must somehow convert obj1 to an A.
            return(0);
            }
            What does the standard say about this? invoking a constructor
            when the object on lvalue is already created...
            Constructors can be used as conversion operators. If all you
            can assign to an A is another A, then the compiler will try to
            convert whatever you have to an A. Using a constructor, if it
            has to.

            After that, the assignment operator is called.

            When trying to follow what the compiler is doing in such cases,
            I would strongly recommend explicitly defining and instrumenting
            the functions that the compiler will otherwise declare and
            define implicitly. You might also want to experiment with
            declaring some of the non-copy constructors explicit; this is
            pretty much standard practice when writing most classes anyway,
            since you generally don't want implicit conversions.

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            Working...