constructor conversion vs operator =

Discussion in 'C++' started by vairavans@gmail.com, Dec 11, 2007.

  1. Guest

    Hi Everyone,

    I have the following code,

    class B
    {
    };

    class A
    {
    public: A()
    {
    }
    A(B& ref_obj)
    {
    printf("conversion\n");
    }
    ~A()
    {
    }
    A operator=(const B& ref)
    {
    printf("operator\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...
     
    , Dec 11, 2007
    #1
    1. Advertising

  2. Ondra Holub Guest

    On 11 Pro, 17:45, wrote:
    > Hi Everyone,
    >
    > I have the following code,
    >
    > class B
    > {
    >
    > };
    >
    > class A
    > {
    > public: A()
    > {
    > }
    > A(B& ref_obj)
    > {
    > printf("conversion\n");
    > }
    > ~A()
    > {
    > }
    > A operator=(const B& ref)
    > {
    > printf("operator\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.
     
    Ondra Holub, Dec 11, 2007
    #2
    1. Advertising

  3. siddhu Guest

    On Dec 11, 11:45 am, wrote:
    > Hi Everyone,
    >
    > I have the following code,
    >
    > class B
    > {
    >
    > };
    >
    > class A
    > {
    > public: A()
    > {
    > }
    > A(B& ref_obj)
    > {
    > printf("conversion\n");
    > }
    > ~A()
    > {
    > }
    > A operator=(const B& ref)
    > {
    > printf("operator\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(provided 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...
     
    siddhu, Dec 11, 2007
    #3
  4. On Dec 11, 9:45 pm, wrote:
    > Hi Everyone,
    >
    > I have the following code,
    >
    > class B
    > {
    >
    > };
    >
    > class A
    > {
    > public: A()
    > {
    > }
    > A(B& ref_obj)
    > {
    > printf("conversion\n");
    > }
    > ~A()
    > {
    > }
    > A operator=(const B& ref)
    > {
    > printf("operator\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("operator\n");
    return A();
    }

    to this:

    A operator=(/* const */ A& ref)
    {
    printf("operator\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.
     
    Abhishek Padmanabh, Dec 12, 2007
    #4
  5. wrote:
    > A operator=(const B& ref)
    > {
    > printf("operator\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.
     
    Juha Nieminen, Dec 12, 2007
    #5
  6. James Kanze Guest

    On Dec 11, 5:45 pm, wrote:
    > I have the following code,


    > class B
    > {
    > };


    > class A
    > {
    > public: A()
    > {
    > }
    > A(B& ref_obj)
    > {
    > printf("conversion\n");
    > }
    > ~A()
    > {
    > }
    > A operator=(const B& ref)
    > {
    > printf("operator\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:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Dec 12, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Lehn
    Replies:
    7
    Views:
    377
    Alf P. Steinbach
    Oct 31, 2005
  2. Arvid Requate
    Replies:
    2
    Views:
    1,023
    Alf P. Steinbach
    Jun 23, 2006
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,342
  4. , India
    Replies:
    2
    Views:
    506
    Fraser Ross
    Sep 15, 2009
  5. Jarek Blakarz
    Replies:
    1
    Views:
    289
    Victor Bazarov
    Oct 10, 2012
Loading...

Share This Page