Unexpected result with virtual operator= overload

Discussion in 'C++' started by Lloyd, Aug 1, 2013.

  1. Lloyd

    Lloyd Guest

    Hi,

    This is a small code piece I have written to test. It is overloading "operator=". To my surprise this code prints "base" always! If I overload "operator+" it prints "derived". Can you give a reason why "=" behaves that way in this code?

    #include <iostream>
    using std::cout;

    class derived;

    class base
    {
    public:
    virtual derived& operator=(const base& rhs);
    };

    class derived: public base
    {
    public:
    derived& operator=(const base& rhs);
    };

    derived x;
    derived& base::eek:perator=(const base& rhs)
    {
    cout<<"base\n";
    return x;
    }

    derived& derived::eek:perator=(const base& rhs)
    {
    cout<<"derived\n";
    return x;
    }

    int main()
    {
    derived d,e;
    d=e;
    return 0;
    }

    Thanks,
    Lloyd
     
    Lloyd, Aug 1, 2013
    #1
    1. Advertising

  2. Lloyd <> wrote:
    > Hi,
    >
    > This is a small code piece I have written to test. It is overloading
    > "operator=". To my surprise this code prints "base" always! If I overload
    > "operator+" it prints "derived". Can you give a reason why "=" behaves
    > that way in this code?
    >
    > #include <iostream>
    > using std::cout;
    >
    > class derived;
    >
    > class base
    > {
    > public:
    > virtual derived& operator=(const base& rhs);


    This is a copy assignment operator for base.
    The return type is unusual but it's a copy assignment operator
    nevertheless.

    > };
    >
    > class derived: public base
    > {
    > public:
    > derived& operator=(const base& rhs);


    This is _not_ a copy assignment operator for derived, the parameter type
    does not match.

    This means that derived has a compiler-generated copy constructor, which
    calls the copy assignment operator for all base classes and members.

    > };
    >
    > derived x;
    > derived& base::eek:perator=(const base& rhs)
    > {
    > cout<<"base\n";
    > return x;
    > }
    >
    > derived& derived::eek:perator=(const base& rhs)
    > {
    > cout<<"derived\n";
    > return x;
    > }
    >
    > int main()
    > {
    > derived d,e;
    > d=e;


    Copy assignment operator for derived is called, not your custom assignment
    operator.

    > return 0;
    > }


    Such unconventional operator overloading only confuses people, including
    yourself. At least the return type should always be the type where the
    operator is declared. And always "return *this;", not some unrelated
    object.

    Tobi
     
    Tobias Müller, Aug 1, 2013
    #2
    1. Advertising

  3. Tobias Müller <> wrote:
    > Lloyd <> wrote:
    >> Hi,
    >>
    >> This is a small code piece I have written to test. It is overloading
    >> "operator=". To my surprise this code prints "base" always! If I overload
    >> "operator+" it prints "derived". Can you give a reason why "=" behaves
    >> that way in this code?
    >>
    >> #include <iostream>
    >> using std::cout;
    >>
    >> class derived;
    >>
    >> class base
    >> {
    >> public:
    >> virtual derived& operator=(const base& rhs);

    >
    > This is a copy assignment operator for base.
    > The return type is unusual but it's a copy assignment operator
    > nevertheless.
    >
    >> };
    >>
    >> class derived: public base
    >> {
    >> public:
    >> derived& operator=(const base& rhs);

    >
    > This is _not_ a copy assignment operator for derived, the parameter type
    > does not match.
    >
    > This means that derived has a compiler-generated copy constructor, which


    Compiler-generated copy assignment operator of course, sorry

    > calls the copy assignment operator for all base classes and members.
    >
    >> };
    >>
    >> derived x;
    >> derived& base::eek:perator=(const base& rhs)
    >> {
    >> cout<<"base\n";
    >> return x;
    >> }
    >>
    >> derived& derived::eek:perator=(const base& rhs)
    >> {
    >> cout<<"derived\n";
    >> return x;
    >> }
    >>
    >> int main()
    >> {
    >> derived d,e;
    >> d=e;

    >
    > Copy assignment operator for derived is called, not your custom assignment
    > operator.
    >
    >> return 0;
    >> }

    >
    > Such unconventional operator overloading only confuses people, including
    > yourself. At least the return type should always be the type where the
    > operator is declared. And always "return *this;", not some unrelated
    > object.
    >
    > Tobi
     
    Tobias Müller, Aug 1, 2013
    #3
  4. Lloyd

    Lloyd Guest

    On Thursday, August 1, 2013 6:04:31 PM UTC+5:30, Tobias Müller wrote:
    > Lloyd <> wrote:
    >
    > > Hi,

    >
    > >

    >
    > > This is a small code piece I have written to test. It is overloading

    >
    > > "operator=". To my surprise this code prints "base" always! If I overload

    >
    > > "operator+" it prints "derived". Can you give a reason why "=" behaves

    >
    > > that way in this code?

    >
    > >

    >
    > > #include <iostream>

    >
    > > using std::cout;

    >
    > >

    >
    > > class derived;

    >
    > >

    >
    > > class base

    >
    > > {

    >
    > > public:

    >
    > > virtual derived& operator=(const base& rhs);

    >
    >
    >
    > This is a copy assignment operator for base.
    >
    > The return type is unusual but it's a copy assignment operator
    >
    > nevertheless.
    >
    >
    >
    > > };

    >
    > >

    >
    > > class derived: public base

    >
    > > {

    >
    > > public:

    >
    > > derived& operator=(const base& rhs);

    >
    >
    >
    > This is _not_ a copy assignment operator for derived, the parameter type
    >
    > does not match.
    >
    >
    >
    > This means that derived has a compiler-generated copy constructor, which
    >
    > calls the copy assignment operator for all base classes and members.
    >
    >
    >
    > > };

    >
    > >

    >
    > > derived x;

    >
    > > derived& base::eek:perator=(const base& rhs)

    >
    > > {

    >
    > > cout<<"base\n";

    >
    > > return x;

    >
    > > }

    >
    > >

    >
    > > derived& derived::eek:perator=(const base& rhs)

    >
    > > {

    >
    > > cout<<"derived\n";

    >
    > > return x;

    >
    > > }

    >
    > >

    >
    > > int main()

    >
    > > {

    >
    > > derived d,e;

    >
    > > d=e;

    >
    >
    >
    > Copy assignment operator for derived is called, not your custom assignment
    >
    > operator.


    Did you mean copy assignment operator for *base* is called?


    >
    >
    >
    > > return 0;

    >
    > > }

    >
    >
    >
    > Such unconventional operator overloading only confuses people, including
    >
    > yourself. At least the return type should always be the type where the
    >
    > operator is declared. And always "return *this;", not some unrelated
    >
    > object.
    >
    >
    >
    > Tobi



    May I know the reason why it prints "derived" when changing the operator from "=" to "+"?. Does operator associativity has some role to play here? Thanks for your detailed explanation

    Lloyd
     
    Lloyd, Aug 1, 2013
    #4
  5. On 8/1/2013 8:59 AM, Lloyd wrote:
    > On Thursday, August 1, 2013 6:04:31 PM UTC+5:30, Tobias Müller wrote:
    >> Lloyd <> wrote:
    >>
    >>> Hi,

    >>
    >>>

    >>
    >>> This is a small code piece I have written to test. It is overloading

    >>
    >>> "operator=". To my surprise this code prints "base" always! If I overload

    >>
    >>> "operator+" it prints "derived". Can you give a reason why "=" behaves

    >>
    >>> that way in this code?

    >>
    >>>

    >>
    >>> #include <iostream>

    >>
    >>> using std::cout;

    >>
    >>>

    >>
    >>> class derived;

    >>
    >>>

    >>
    >>> class base

    >>
    >>> {

    >>
    >>> public:

    >>
    >>> virtual derived& operator=(const base& rhs);

    >>
    >>
    >>
    >> This is a copy assignment operator for base.
    >>
    >> The return type is unusual but it's a copy assignment operator
    >>
    >> nevertheless.
    >>
    >>
    >>
    >>> };

    >>
    >>>

    >>
    >>> class derived: public base

    >>
    >>> {

    >>
    >>> public:

    >>
    >>> derived& operator=(const base& rhs);

    >>
    >>
    >>
    >> This is _not_ a copy assignment operator for derived, the parameter type
    >>
    >> does not match.
    >>
    >>
    >>
    >> This means that derived has a compiler-generated copy constructor, which
    >>
    >> calls the copy assignment operator for all base classes and members.
    >>
    >>
    >>
    >>> };

    >>
    >>>

    >>
    >>> derived x;

    >>
    >>> derived& base::eek:perator=(const base& rhs)

    >>
    >>> {

    >>
    >>> cout<<"base\n";

    >>
    >>> return x;

    >>
    >>> }

    >>
    >>>

    >>
    >>> derived& derived::eek:perator=(const base& rhs)

    >>
    >>> {

    >>
    >>> cout<<"derived\n";

    >>
    >>> return x;

    >>
    >>> }

    >>
    >>>

    >>
    >>> int main()

    >>
    >>> {

    >>
    >>> derived d,e;

    >>
    >>> d=e;

    >>
    >>
    >>
    >> Copy assignment operator for derived is called, not your custom assignment
    >>
    >> operator.

    >
    > Did you mean copy assignment operator for *base* is called?


    No. If you declare/define your own *correct* copy assignment op in
    'derived', you are going to see it used. The implicitly declared (and
    implicitly defined) one in this case behaves as it should - it simply
    calls the base copy assignment op that *you* defined.

    >>
    >>
    >>
    >>> return 0;

    >>
    >>> }

    >>
    >>
    >>
    >> Such unconventional operator overloading only confuses people, including
    >>
    >> yourself. At least the return type should always be the type where the
    >>
    >> operator is declared. And always "return *this;", not some unrelated
    >>
    >> object.
    >>
    >>
    >>
    >> Tobi

    >
    >
    > May I know the reason why it prints "derived" when changing the operator from "=" to "+"?. Does operator associativity has some role to play here? Thanks for your detailed explanation


    No. These operators do differ in this important aspect: there is no
    implicitly defined operator+, but there *is* an implicitly defined copy
    assignment op (which you didn't see called in your original example).

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 1, 2013
    #5
  6. Lloyd

    Lloyd Guest

    On Thursday, August 1, 2013 6:33:52 PM UTC+5:30, Victor Bazarov wrote:
    > On 8/1/2013 8:59 AM, Lloyd wrote:
    >
    > > On Thursday, August 1, 2013 6:04:31 PM UTC+5:30, Tobias Müller wrote:

    >
    > >> Lloyd <> wrote:

    >
    > >>

    >
    > >>> Hi,

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> This is a small code piece I have written to test. It is overloading

    >
    > >>

    >
    > >>> "operator=". To my surprise this code prints "base" always! If I overload

    >
    > >>

    >
    > >>> "operator+" it prints "derived". Can you give a reason why "=" behaves

    >
    > >>

    >
    > >>> that way in this code?

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> #include <iostream>

    >
    > >>

    >
    > >>> using std::cout;

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> class derived;

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> class base

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> public:

    >
    > >>

    >
    > >>> virtual derived& operator=(const base& rhs);

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> This is a copy assignment operator for base.

    >
    > >>

    >
    > >> The return type is unusual but it's a copy assignment operator

    >
    > >>

    >
    > >> nevertheless.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >>> };

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> class derived: public base

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> public:

    >
    > >>

    >
    > >>> derived& operator=(const base& rhs);

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> This is _not_ a copy assignment operator for derived, the parameter type

    >
    > >>

    >
    > >> does not match.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> This means that derived has a compiler-generated copy constructor, which

    >
    > >>

    >
    > >> calls the copy assignment operator for all base classes and members.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >>> };

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> derived x;

    >
    > >>

    >
    > >>> derived& base::eek:perator=(const base& rhs)

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> cout<<"base\n";

    >
    > >>

    >
    > >>> return x;

    >
    > >>

    >
    > >>> }

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> derived& derived::eek:perator=(const base& rhs)

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> cout<<"derived\n";

    >
    > >>

    >
    > >>> return x;

    >
    > >>

    >
    > >>> }

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> int main()

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> derived d,e;

    >
    > >>

    >
    > >>> d=e;

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> Copy assignment operator for derived is called, not your custom assignment

    >
    > >>

    >
    > >> operator.

    >
    > >

    >
    > > Did you mean copy assignment operator for *base* is called?

    >
    >
    >
    > No. If you declare/define your own *correct* copy assignment op in
    >
    > 'derived', you are going to see it used. The implicitly declared (and
    >
    > implicitly defined) one in this case behaves as it should - it simply
    >
    > calls the base copy assignment op that *you* defined.
    >
    >
    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >>> return 0;

    >
    > >>

    >
    > >>> }

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> Such unconventional operator overloading only confuses people, including

    >
    > >>

    >
    > >> yourself. At least the return type should always be the type where the

    >
    > >>

    >
    > >> operator is declared. And always "return *this;", not some unrelated

    >
    > >>

    >
    > >> object.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> Tobi

    >
    > >

    >
    > >

    >
    > > May I know the reason why it prints "derived" when changing the operator from "=" to "+"?. Does operator associativity has some role to play here? Thanks for your detailed explanation

    >
    >
    >
    > No. These operators do differ in this important aspect: there is no
    >
    > implicitly defined operator+, but there *is* an implicitly defined copy
    >
    > assignment op (which you didn't see called in your original example).
    >
    >
    >
    > V
    >


    Thank you very much. Now I clearly understood.



    > --
    >
    > I do not respond to top-posted replies, please don't ask
     
    Lloyd, Aug 1, 2013
    #6
  7. Lloyd

    osmium Guest

    "Lloyd" wrote:

    <google munged>
    On Thursday, August 1, 2013 6:33:52 PM UTC+5:30, Victor Bazarov wrote:
    > On 8/1/2013 8:59 AM, Lloyd wrote:
    >
    > > On Thursday, August 1, 2013 6:04:31 PM UTC+5:30, Tobias Müller wrote:

    >
    > >> Lloyd <> wrote:

    >
    > >>

    >
    > >>> Hi,

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> This is a small code piece I have written to test. It is overloading

    >
    > >>

    >
    > >>> "operator=". To my surprise this code prints "base" always! If I
    > >>> overload

    >
    > >>

    >
    > >>> "operator+" it prints "derived". Can you give a reason why "=" behaves

    >
    > >>

    >
    > >>> that way in this code?

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> #include <iostream>

    >
    > >>

    >
    > >>> using std::cout;

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> class derived;

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> class base

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> public:

    >
    > >>

    >
    > >>> virtual derived& operator=(const base& rhs);

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> This is a copy assignment operator for base.

    >
    > >>

    >
    > >> The return type is unusual but it's a copy assignment operator

    >
    > >>

    >
    > >> nevertheless.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >>> };

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> class derived: public base

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> public:

    >
    > >>

    >
    > >>> derived& operator=(const base& rhs);

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> This is _not_ a copy assignment operator for derived, the parameter
    > >> type

    >
    > >>

    >
    > >> does not match.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> This means that derived has a compiler-generated copy constructor,
    > >> which

    >
    > >>

    >
    > >> calls the copy assignment operator for all base classes and members.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >>> };

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> derived x;

    >
    > >>

    >
    > >>> derived& base::eek:perator=(const base& rhs)

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> cout<<"base\n";

    >
    > >>

    >
    > >>> return x;

    >
    > >>

    >
    > >>> }

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> derived& derived::eek:perator=(const base& rhs)

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> cout<<"derived\n";

    >
    > >>

    >
    > >>> return x;

    >
    > >>

    >
    > >>> }

    >
    > >>

    >
    > >>>

    >
    > >>

    >
    > >>> int main()

    >
    > >>

    >
    > >>> {

    >
    > >>

    >
    > >>> derived d,e;

    >
    > >>

    >
    > >>> d=e;

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> Copy assignment operator for derived is called, not your custom
    > >> assignment

    >
    > >>

    >
    > >> operator.

    >
    > >

    >
    > > Did you mean copy assignment operator for *base* is called?

    >
    >
    >
    > No. If you declare/define your own *correct* copy assignment op in
    >
    > 'derived', you are going to see it used. The implicitly declared (and
    >
    > implicitly defined) one in this case behaves as it should - it simply
    >
    > calls the base copy assignment op that *you* defined.
    >
    >
    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >>> return 0;

    >
    > >>

    >
    > >>> }

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> Such unconventional operator overloading only confuses people,
    > >> including

    >
    > >>

    >
    > >> yourself. At least the return type should always be the type where the

    >
    > >>

    >
    > >> operator is declared. And always "return *this;", not some unrelated

    >
    > >>

    >
    > >> object.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> Tobi

    >
    > >

    >
    > >

    >
    > > May I know the reason why it prints "derived" when changing the operator
    > > from "=" to "+"?. Does operator associativity has some role to play
    > > here? Thanks for your detailed explanation

    >
    >
    >
    > No. These operators do differ in this important aspect: there is no
    >
    > implicitly defined operator+, but there *is* an implicitly defined copy
    >
    > assignment op (which you didn't see called in your original example).
    >
    >
    >
    > V
    >


    Thank you very much. Now I clearly understood.
    <end google>

    Thanks to google and their utter contempt for standards, that post is almost
    entirely white space.

    There must be a science fiction story that describes this situation very
    well? Kind of a spin-off of Tower of Babel.
     
    osmium, Aug 1, 2013
    #7
  8. Lloyd

    Öö Tiib Guest

    On Thursday, 1 August 2013 15:34:31 UTC+3, Tobias Müller wrote:
    > Lloyd <> wrote:
    > > This is a small code piece I have written to test. It is overloading
    > > "operator=". To my surprise this code prints "base" always! If I overload
    > > "operator+" it prints "derived". Can you give a reason why "=" behaves
    > > that way in this code?
    > >
    > > #include <iostream>
    > > using std::cout;
    > >
    > > class derived;
    > >
    > > class base
    > > {
    > > public:
    > > virtual derived& operator=(const base& rhs);

    >
    > This is a copy assignment operator for base.
    > The return type is unusual but it's a copy assignment operator
    > nevertheless.


    Another thing that is unusual is that it is virtual. I have usually
    reviewed such things as defects, since I can't imagine how that virtual
    assignment should work.


    > > };
    > >
    > > class derived: public base
    > > {
    > > public:
    > > derived& operator=(const base& rhs);

    >
    > This is _not_ a copy assignment operator for derived, the parameter type
    > does not match.


    Is not it also override of the virtual copy assignment operator of base class?

    > This means that derived has a compiler-generated copy constructor, which
    > calls the copy assignment operator for all base classes and members.


    Interesting, why the override copy assignment operator is not called?
     
    Öö Tiib, Aug 1, 2013
    #8
  9. On 8/1/2013 10:33 AM, Öö Tiib wrote:
    > On Thursday, 1 August 2013 15:34:31 UTC+3, Tobias Müller wrote:
    >> Lloyd <> wrote:
    >>> This is a small code piece I have written to test. It is overloading
    >>> "operator=". To my surprise this code prints "base" always! If I overload
    >>> "operator+" it prints "derived". Can you give a reason why "=" behaves
    >>> that way in this code?
    >>>
    >>> #include <iostream>
    >>> using std::cout;
    >>>
    >>> class derived;
    >>>
    >>> class base
    >>> {
    >>> public:
    >>> virtual derived& operator=(const base& rhs);

    >>
    >> This is a copy assignment operator for base.
    >> The return type is unusual but it's a copy assignment operator
    >> nevertheless.

    >
    > Another thing that is unusual is that it is virtual. I have usually
    > reviewed such things as defects, since I can't imagine how that virtual
    > assignment should work.


    If you actually assign to a derived object using a reference to base,
    the *derived* assignment operator is called. Some could find it useful.
    I know of no case that calls for it, but see no particular reason to
    prohibit it.

    >>> };
    >>>
    >>> class derived: public base
    >>> {
    >>> public:
    >>> derived& operator=(const base& rhs);

    >>
    >> This is _not_ a copy assignment operator for derived, the parameter type
    >> does not match.

    >
    > Is not it also override of the virtual copy assignment operator of base class?


    That's the intention, I believe.

    >> This means that derived has a compiler-generated copy constructor, which
    >> calls the copy assignment operator for all base classes and members.

    >
    > Interesting, why the override copy assignment operator is not called?


    The implicitly defined copy assignment op calls base classes' (and
    members') assignment operators as if with the scope resolution, I think.
    And when base:: is used, it circumvents the polymorphic call. That's
    my take on it, anyway.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 1, 2013
    #9
  10. Lloyd

    Öö Tiib Guest

    On Thursday, 1 August 2013 17:47:29 UTC+3, Victor Bazarov wrote:
    > On 8/1/2013 10:33 AM, Öö Tiib wrote:
    > > On Thursday, 1 August 2013 15:34:31 UTC+3, Tobias Müller wrote:
    > >> Lloyd <> wrote:
    > >>> This is a small code piece I have written to test. It is overloading
    > >>> "operator=". To my surprise this code prints "base" always! If I overload
    > >>> "operator+" it prints "derived". Can you give a reason why "=" behaves
    > >>> that way in this code?
    > >>>
    > >>> #include <iostream>
    > >>> using std::cout;
    > >>>
    > >>> class derived;
    > >>>
    > >>> class base
    > >>> {
    > >>> public:
    > >>> virtual derived& operator=(const base& rhs);
    > >>
    > >> This is a copy assignment operator for base.
    > >> The return type is unusual but it's a copy assignment operator
    > >> nevertheless.

    > >
    > > Another thing that is unusual is that it is virtual. I have usually
    > > reviewed such things as defects, since I can't imagine how that virtual
    > > assignment should work.

    >
    > If you actually assign to a derived object using a reference to base,
    > the *derived* assignment operator is called. Some could find it useful.
    > I know of no case that calls for it, but see no particular reason to
    > prohibit it.


    On all cases when I have seen "virtual operator=" it was either seeking
    ways to assign apples to oranges (slicing defect) or using "operator="
    for something else but copy-assignment (confusing). I would like to see
    any better case.

    When we need polymorphism (for example to implement a casket of fruits)
    in C++ then we use base (fruit) pointers. How else? Now when we need to exchange polymorphic objects (arrange the apples and oranges around in
    such casket) then most efficient seems to be to modify the values of
    such pointers instead of values of the objects. Idiomatically the
    polymorphic objects should be clone-able instead of being copyable.

    > >> This means that derived has a compiler-generated copy constructor, which
    > >> calls the copy assignment operator for all base classes and members.

    > >
    > > Interesting, why the override copy assignment operator is not called?

    >
    > The implicitly defined copy assignment op calls base classes' (and
    > members') assignment operators as if with the scope resolution, I think.
    > And when base:: is used, it circumvents the polymorphic call. That's
    > my take on it, anyway.


    Yes, that makes sense. Thanks, I had not even thought of that.
     
    Öö Tiib, Aug 2, 2013
    #10
  11. On 8/2/2013 6:33 AM, Öö Tiib wrote:
    > On Thursday, 1 August 2013 17:47:29 UTC+3, Victor Bazarov wrote:
    >> On 8/1/2013 10:33 AM, Öö Tiib wrote:
    >>> [..]
    >>> Another thing that is unusual is that it is virtual. I have usually
    >>> reviewed such things as defects, since I can't imagine how that virtual
    >>> assignment should work.

    >>
    >> If you actually assign to a derived object using a reference to base,
    >> the *derived* assignment operator is called. Some could find it useful.
    >> I know of no case that calls for it, but see no particular reason to
    >> prohibit it.

    >
    > On all cases when I have seen "virtual operator=" it was either seeking
    > ways to assign apples to oranges (slicing defect) or using "operator="
    > for something else but copy-assignment (confusing). I would like to see
    > any better case.


    Perhaps we get lucky and in our lifetime we come across some piece of
    code that does something useful with a virtual copy assignment op. I
    haven't seen one such example either. Still, not a valid reason to
    prohibit it.

    > When we need polymorphism (for example to implement a casket of fruits)
    > in C++ then we use base (fruit) pointers. How else? Now when we need to exchange polymorphic objects (arrange the apples and oranges around in
    > such casket) then most efficient seems to be to modify the values of
    > such pointers instead of values of the objects. Idiomatically the
    > polymorphic objects should be clone-able instead of being copyable.


    That concerns collections of heterogeneous objects. What if the
    collection is not the context of such an assignment, but instead it is
    hidden deep in some library code and a reference is used to avoid
    slicing and the caller of the library wants to register the fact that
    the derived object was being assigned to? Just one possible scenario.

    > [..]


    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 2, 2013
    #11
    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. Mike Pemberton

    unexpected result using std::list

    Mike Pemberton, Oct 14, 2003, in forum: C++
    Replies:
    3
    Views:
    353
    Dan Cernat
    Oct 14, 2003
  2. Piotre Ugrumov
    Replies:
    3
    Views:
    384
    Nick Hounsome
    Jan 25, 2004
  3. Michael Tan
    Replies:
    32
    Views:
    1,049
    Ara.T.Howard
    Jul 21, 2005
  4. Andy Tolle
    Replies:
    7
    Views:
    246
    Andy Tolle
    Nov 15, 2010
  5. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    274
    Sherm Pendley
    Oct 11, 2004
Loading...

Share This Page