operator= for derived class

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • MojoRison

    operator= for derived class

    struct A{
    A& operator=( const A& a ){ i = a.i; return *this; }

    private:
    int i;
    };

    struct B : public A{
    B& operator=( const B& b ){ j = b.j; return *this; } // how to copy i?

    private:
    int j;
    };

    In the above code, what would be the standard way of coping A::i in
    B::operator= ?


  • Victor Bazarov

    #2
    Re: operator= for derived class

    MojoRison wrote:[color=blue]
    > struct A{
    > A& operator=( const A& a ){ i = a.i; return *this; }
    >
    > private:
    > int i;
    > };
    >
    > struct B : public A{
    > B& operator=( const B& b ){ j = b.j; return *this; } // how to copy i?
    >
    > private:
    > int j;
    > };
    >
    > In the above code, what would be the standard way of coping A::i in
    > B::operator= ?[/color]


    For the classes in their presented form, there is no need for operator=.
    But you probably already knew that.

    The simple way is to call the A::operator= directly inside B::operator= :

    B& operator=(const B& b) { A::operator=(b) ; j = b.j; return *this }

    Victor

    Comment

    • Andrey Tarasevich

      #3
      Re: operator= for derived class

      MojoRison wrote:
      [color=blue]
      > struct A{
      > A& operator=( const A& a ){ i = a.i; return *this; }
      >
      > private:
      > int i;
      > };
      >
      > struct B : public A{
      > B& operator=( const B& b ){ j = b.j; return *this; } // how to copy i?
      >
      > private:
      > int j;
      > };
      >
      > In the above code, what would be the standard way of coping A::i in
      > B::operator= ?[/color]

      Firstly, for such classes you don't need to implement the copy
      assignment operator explicitly. The one automatically provided by the
      compiler will do exactly what you want.

      If you still want to implement these operators manually, then the proper
      way to do it would be calling the inherited copy assignment operator
      ('A::operator=' ) from B's implementation

      B& operator=( const B& b ) {
      A::operator=(b) ;
      j = b.j;
      return *this;
      }

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • Thomas Matthews

        #4
        Re: operator= for derived class

        MojoRison wrote:[color=blue]
        > struct A{
        > A& operator=( const A& a ){ i = a.i; return *this; }
        >
        > private:
        > int i;
        > };
        >
        > struct B : public A{
        > B& operator=( const B& b ){ j = b.j; return *this; } // how to copy i?
        >
        > private:
        > int j;
        > };
        >
        > In the above code, what would be the standard way of coping A::i in
        > B::operator= ?
        >
        >[/color]

        I would make the operator= in the parent class
        protected. This would prevent "slicing", where only the
        parent portion is copied. See [1] below.

        One method of implementing assignment operator in child
        classes is:
        Child&
        Child ::
        operator=(const Child& ch)
        {
        if (this != &child) /* guard against self assignment */
        {
        (Parent&)(*this ) = (Parent&)(ch);
        /* assignment of child members */
        }
        return *this;
        }
        The above fragment comes from Effective C++ or More Effective C++
        by Scott Meyers.

        [1] When parents allow public assignment, one can assign the
        parent portion of child A to child B, using pointers to
        the parent class.
        struct Parent
        {
        Parent& operator=(const Parent& p);
        };

        struct Son : Parent
        {
        Son& operator=(const Son& s);
        };

        struct Daughter : Parent
        {
        Daughter& operator=(const Daughter& d);
        };

        /* ... */

        Son bill;
        Son jack;
        Daughter amy;
        Parent * p_male = &bill;
        Parent * p_female = &amy;
        Parent * p_brother = & jack;
        *p_brother = *p_male; /* Are the child members copied? */
        /* One _might_ think so... */
        *p_male = *p_female; /* copies only parent portion */
        /* Do you want this allowed? */

        This has cost me many hours of debugging, so I've learned
        to make assignment operators of base classes as protected.
        to prevent the above scenario from occurring.

        --
        Thomas Matthews

        C++ newsgroup welcome message:

        C++ Faq: http://www.parashift.com/c++-faq-lite
        C Faq: http://www.eskimo.com/~scs/c-faq/top.html
        alt.comp.lang.l earn.c-c++ faq:

        Other sites:
        http://www.josuttis.com -- C++ STL Library book
        http://www.sgi.com/tech/stl -- Standard Template Library

        Comment

        Working...