Reference assignment through base class reference

Discussion in 'C++' started by siddhu, Jun 4, 2007.

  1. siddhu

    siddhu Guest

    Dear experts,


    #include <stdio.h>

    class Base
    {
    };
    class Der1:public Base
    {
    };
    class Der2:public Base
    {
    };

    int main()
    {
    Der1 d1;Der2 d2;
    Base& b1 = d1;
    Base& b2 = d2;
    b1 = b2;
    }

    Above code gets compiled. But I wonder what does the assignment b1 =
    b2; do?If these are pointers then its understandable. But how does
    above assignment behave in case of references. Does it exhibit UB?

    Regards,
    Siddharth
     
    siddhu, Jun 4, 2007
    #1
    1. Advertising

  2. siddhu wrote:
    > Dear experts,
    >
    >
    > #include <stdio.h>
    >
    > class Base
    > {
    > };
    > class Der1:public Base
    > {
    > };
    > class Der2:public Base
    > {
    > };
    >
    > int main()
    > {
    > Der1 d1;Der2 d2;
    > Base& b1 = d1;
    > Base& b2 = d2;
    > b1 = b2;
    > }
    >
    > Above code gets compiled. But I wonder what does the assignment b1 =
    > b2; do?If these are pointers then its understandable. But how does
    > above assignment behave in case of references. Does it exhibit UB?
    >


    No UB here. Your class might not expect it though. It is commonly
    referred to as "slicing". It's also usually not something that is
    expected to happen in the implementation and so things can co awry.

    It can be prevented by making the base class constructor "protected".
     
    Gianni Mariani, Jun 4, 2007
    #2
    1. Advertising

  3. siddhu wrote:
    > #include <stdio.h>

    ^^^^^^^^^^^^^^^^
    What's that for?

    >
    > class Base
    > {
    > };
    > class Der1:public Base
    > {
    > };
    > class Der2:public Base
    > {
    > };
    >
    > int main()
    > {
    > Der1 d1;Der2 d2;
    > Base& b1 = d1;
    > Base& b2 = d2;
    > b1 = b2;
    > }
    >
    > Above code gets compiled. But I wonder what does the assignment b1 =
    > b2; do?If these are pointers then its understandable. But how does
    > above assignment behave in case of references. Does it exhibit UB?


    No, no UB. 'Base' subobject of 'd1' gets the same 'Base' value as
    the 'Base' subobject of 'd2'.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 4, 2007
    #3
  4. Gianni Mariani wrote:
    > siddhu wrote:
    >> Dear experts,
    >>
    >>
    >> #include <stdio.h>
    >>
    >> class Base
    >> {
    >> };
    >> class Der1:public Base
    >> {
    >> };
    >> class Der2:public Base
    >> {
    >> };
    >>
    >> int main()
    >> {
    >> Der1 d1;Der2 d2;
    >> Base& b1 = d1;
    >> Base& b2 = d2;
    >> b1 = b2;
    >> }
    >>
    >> Above code gets compiled. But I wonder what does the assignment b1 =
    >> b2; do?If these are pointers then its understandable. But how does
    >> above assignment behave in case of references. Does it exhibit UB?
    >>

    >
    > No UB here. Your class might not expect it though. It is commonly
    > referred to as "slicing". It's also usually not something that is
    > expected to happen in the implementation and so things can co awry.
    >
    > It can be prevented by making the base class constructor "protected".


    Constructor? Not the copy assignment operator? How does slicing get
    into copy assigning objects through references, by the way?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 4, 2007
    #4
  5. Victor Bazarov wrote:
    ...
    > Constructor? Not the copy assignment operator? How does slicing get
    > into copy assigning objects through references, by the way?
    >


    My excuse is I'm sick and I'm sticking to it ...
     
    Gianni Mariani, Jun 5, 2007
    #5
  6. siddhu

    BobR Guest

    Gianni Mariani wrote in message...
    > Victor Bazarov wrote:
    > ..
    > > Constructor? Not the copy assignment operator? How does slicing get
    > > into copy assigning objects through references, by the way?
    > >

    >
    > My excuse is I'm sick and I'm sticking to it ...


    Take two aspirin and call Dr. Dobbs in the morning! <G>

    --
    Bob <G> R
    POVrookie
     
    BobR, Jun 5, 2007
    #6
  7. siddhu

    James Kanze Guest

    On Jun 4, 10:49 pm, siddhu <> wrote:
    > #include <stdio.h>


    > class Base
    > {};


    > class Der1:public Base
    > {
    > };
    > class Der2:public Base
    > {
    > };


    > int main()
    > {
    > Der1 d1;Der2 d2;
    > Base& b1 = d1;
    > Base& b2 = d2;
    > b1 = b2;
    > }


    > Above code gets compiled. But I wonder what does the
    > assignment b1 = b2; do?


    Nothing useful. It assigns the Base part of d2 to the Base part
    of d1.

    > If these are pointers then its understandable. But how does
    > above assignment behave in case of references. Does it exhibit UB?


    Not directly. Of course, class invariants are likely broken,
    but that's not a language problem---the language specifies a
    behavior here.

    In general, assignment doesn't work well with polymorphic
    objects. Typically, if a class is designed to be used as a
    base, it will have a private assignment operator, so that such
    code will be illegal.

    --
    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, Jun 5, 2007
    #7
  8. James Kanze wrote:
    > [..]
    > In general, assignment doesn't work well with polymorphic
    > objects. Typically, if a class is designed to be used as a
    > base, it will have a private assignment operator, so that such
    > code will be illegal.


    *Private* assignment operator? Not *protected*? Just trying to
    clarify...

    Thanks!

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 5, 2007
    #8
  9. siddhu

    James Kanze Guest

    On Jun 5, 3:06 pm, "Victor Bazarov" <> wrote:
    > James Kanze wrote:
    > > [..]
    > > In general, assignment doesn't work well with polymorphic
    > > objects. Typically, if a class is designed to be used as a
    > > base, it will have a private assignment operator, so that such
    > > code will be illegal.


    > *Private* assignment operator? Not *protected*? Just trying to
    > clarify...


    Private. Why would you make it protected, if the goal is to ban
    it? Alternatively, you could inherit from something like
    boost::uncopiable.

    --
    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, Jun 5, 2007
    #9
  10. James Kanze wrote:
    > On Jun 5, 3:06 pm, "Victor Bazarov" <> wrote:
    >> James Kanze wrote:
    >>> [..]
    >>> In general, assignment doesn't work well with polymorphic
    >>> objects. Typically, if a class is designed to be used as a
    >>> base, it will have a private assignment operator, so that such
    >>> code will be illegal.

    >
    >> *Private* assignment operator? Not *protected*? Just trying to
    >> clarify...

    >
    > Private. Why would you make it protected, if the goal is to ban
    > it? Alternatively, you could inherit from something like
    > boost::uncopiable.


    If a class is designed to be used as a base, and its assignment op
    is private, how the hell are you going to copy the derived class
    objects? The default copy assignment op cannot be generated, so
    a user-defined has to be provided, which will have to forgo copying
    of the base part, which means only the derived portion can be made
    "the same as the other one", and the base class subobject will have
    to stay the way it was created... That's just wrong, it meanst that
    if I have

    Derived d1(some_params), d2(some_other_params); // different
    assert(d1 != d2);
    d1 = d2;
    assert(d1 == d2); // how is that going to be true if '=='
    // compares the base part as well?

    So, either _in_general_ comparing objects of derived class should
    NOT involve comparing base class subobjects (which is just wrong
    *in general*), or there should be a way to assign bass class
    subobjects in a derived class copy assignment operator, which
    means the copy assignment operator should be probably *protected*
    _in_general_ if the class is intended to serve as a base.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 5, 2007
    #10
  11. siddhu

    James Kanze Guest

    On Jun 5, 7:27 pm, "Victor Bazarov" <> wrote:
    > James Kanze wrote:
    > > On Jun 5, 3:06 pm, "Victor Bazarov" <> wrote:
    > >> James Kanze wrote:
    > >>> [..]
    > >>> In general, assignment doesn't work well with polymorphic
    > >>> objects. Typically, if a class is designed to be used as a
    > >>> base, it will have a private assignment operator, so that such
    > >>> code will be illegal.


    > >> *Private* assignment operator? Not *protected*? Just trying to
    > >> clarify...


    > > Private. Why would you make it protected, if the goal is to ban
    > > it? Alternatively, you could inherit from something like
    > > boost::uncopiable.


    > If a class is designed to be used as a base, and its assignment op
    > is private, how the hell are you going to copy the derived class
    > objects?


    You're not going to assign them. (A protected copy constructor
    is sometimes appropriate. Although in most cases, if a class is
    designed to be used as a base class, it has no data to be
    copied.)

    > The default copy assignment op cannot be generated, so
    > a user-defined has to be provided, which will have to forgo copying
    > of the base part, which means only the derived portion can be made
    > "the same as the other one", and the base class subobject will have
    > to stay the way it was created...


    No. The derived class doesn't have to do anything. Assignment
    is just not part of the contract, and thus not supported.

    --
    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, Jun 6, 2007
    #11
  12. James Kanze wrote:
    > On Jun 5, 7:27 pm, "Victor Bazarov" <> wrote:
    >> James Kanze wrote:
    >>> On Jun 5, 3:06 pm, "Victor Bazarov" <> wrote:
    >>>> James Kanze wrote:
    >>>>> [..]
    >>>>> In general, assignment doesn't work well with polymorphic
    >>>>> objects. Typically, if a class is designed to be used as a
    >>>>> base, it will have a private assignment operator, so that such
    >>>>> code will be illegal.

    >
    >>>> *Private* assignment operator? Not *protected*? Just trying to
    >>>> clarify...

    >
    >>> Private. Why would you make it protected, if the goal is to ban
    >>> it? Alternatively, you could inherit from something like
    >>> boost::uncopiable.

    >
    >> If a class is designed to be used as a base, and its assignment op
    >> is private, how the hell are you going to copy the derived class
    >> objects?

    >
    > You're not going to assign them. (A protected copy constructor
    > is sometimes appropriate. Although in most cases, if a class is
    > designed to be used as a base class, it has no data to be
    > copied.)


    "In most cases" is no substitute for "in general". In general even
    a class designed to be a base class _may_ contain data [to be copied].
    So, in my book, *in general* the copy assignment operator cannot be
    private, it has to be protected.

    >> The default copy assignment op cannot be generated, so
    >> a user-defined has to be provided, which will have to forgo copying
    >> of the base part, which means only the derived portion can be made
    >> "the same as the other one", and the base class subobject will have
    >> to stay the way it was created...

    >
    > No. The derived class doesn't have to do anything. Assignment
    > is just not part of the contract, and thus not supported.


    WHAT contract are you talking about? "Assignable" is a requirement
    for an object to be stored in a standard container, for example.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 6, 2007
    #12
  13. James Kanze wrote:
    ....
    >
    > No. The derived class doesn't have to do anything. Assignment
    > is just not part of the contract, and thus not supported.


    Based on the OP code, I think it was clear that he wanted his classes to
    support assignment. The OP just wasn't sure what slicing would do. The
    proposal to "protect" the base class assignment operator was simply a
    suggestion as a way to disallow assignment other than from a derived class.
     
    Gianni Mariani, Jun 6, 2007
    #13
    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. Karl Heinz Buchegger
    Replies:
    3
    Views:
    532
    Karl Heinz Buchegger
    Aug 6, 2003
  2. John Harrison
    Replies:
    0
    Views:
    494
    John Harrison
    Aug 6, 2003
  3. Stephan Br?nnimann

    "Assignment" through base class

    Stephan Br?nnimann, Aug 9, 2004, in forum: C++
    Replies:
    2
    Views:
    380
    Stephan Br?nnimann
    Aug 9, 2004
  4. user
    Replies:
    1
    Views:
    404
    Jack Klein
    Jul 11, 2005
  5. Replies:
    11
    Views:
    593
Loading...

Share This Page