default implementation of assignment operator

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

    #1

    default implementation of assignment operator

    Hello everyone,


    I am wondering the default implementation of assignment operator (e.g.
    when we do not implement assignment operator in user defined class,
    what will be returned? temporary object? reference or const reference?
    deep copy or shallow copy is used in default assignment operator?)? I
    have the C++ Programming Book at hand, but can not find it from Index
    page.


    thanks in advance,
    George
  • Juha Nieminen

    #2
    Re: default implementation of assignment operator

    George2 wrote:
    I am wondering the default implementation of assignment operator (e.g.
    when we do not implement assignment operator in user defined class,
    what will be returned? temporary object? reference or const reference?
    deep copy or shallow copy is used in default assignment operator?)?
    The compiler cannot automatically generate a deep-copying of the
    objects because it has absolutely no way of knowing whether the member
    pointers are pointing at memory allocated and owned by the object
    itself, or whether they are just pointing to something else (for example
    trying to deep-copy an element of a doubly-linked list would be quite a
    bad idea).
    The default assignment operator simply assigns each individual member
    variable from the parameter to this, regardless of what it is. If it's
    eg. a pointer, then a simple pointer assignment will be done.

    In many cases the default assignment operator is ok, especially if the
    class does not contain pointers.

    It returns a const-reference to *this.

    Comment

    • Abhishek Padmanabh

      #3
      Re: default implementation of assignment operator

      On Dec 15, 4:22 pm, Juha Nieminen <nos...@thanks. invalidwrote:
      George2 wrote:
      I am wondering the default implementation of assignment operator (e.g.
      when we do not implement assignment operator in user defined class,
      what will be returned? temporary object? reference or const reference?
      deep copy or shallow copy is used in default assignment operator?)?
      >
      The compiler cannot automatically generate a deep-copying of the
      objects because it has absolutely no way of knowing whether the member
      pointers are pointing at memory allocated and owned by the object
      itself, or whether they are just pointing to something else (for example
      trying to deep-copy an element of a doubly-linked list would be quite a
      bad idea).
      The default assignment operator simply assigns each individual member
      variable from the parameter to this, regardless of what it is. If it's
      eg. a pointer, then a simple pointer assignment will be done.
      >
      In many cases the default assignment operator is ok, especially if the
      class does not contain pointers.
      >
      It returns a const-reference to *this.
      Not a const reference.

      Comment

      • James Kanze

        #4
        Re: default implementation of assignment operator

        On Dec 15, 7:06 am, George2 <george4acade.. .@yahoo.comwrot e:
        I am wondering the default implementation of assignment
        operator (e.g. when we do not implement assignment operator
        in user defined class, what will be returned? temporary
        object? reference or const reference? deep copy or shallow
        copy is used in default assignment operator?)? I have the C++
        Programming Book at hand, but can not find it from Index page.
        It does member by member assignment. Whether this does a deep
        copy or a shallow one depends on the assignment operators in the
        members, for raw pointers, it is shallow, since pointer
        assignment is shallow.

        The signature of the operator, for a class T, is usually:
        T& T::operator=( T const& )
        If any of the base classes or members have a copy assignment
        operator which requires a non-const reference, however, the
        parameter will be a non-const reference.

        --
        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

        • Jim Langston

          #5
          Re: default implementation of assignment operator

          Juha Nieminen wrote:
          George2 wrote:
          >I am wondering the default implementation of assignment operator
          >(e.g. when we do not implement assignment operator in user defined
          >class, what will be returned? temporary object? reference or const
          >reference? deep copy or shallow copy is used in default assignment
          >operator?)?
          >
          The compiler cannot automatically generate a deep-copying of the
          objects because it has absolutely no way of knowing whether the member
          pointers are pointing at memory allocated and owned by the object
          itself, or whether they are just pointing to something else (for
          example trying to deep-copy an element of a doubly-linked list would
          be quite a bad idea).
          The default assignment operator simply assigns each individual member
          variable from the parameter to this, regardless of what it is. If it's
          eg. a pointer, then a simple pointer assignment will be done.
          >
          In many cases the default assignment operator is ok, especially if
          the class does not contain pointers.
          >
          It returns a const-reference to *this.
          This behavior is sometimes refered to as a "bitwise copy" although that is
          not strictly true. If it was a bitwise copy, copying the bits of the class
          ignoring constructors, then there would be different values then there are.

          Basically it will take the base copy of whatever types are being copied.
          For most things this is fine. This will work for stl::containers ,
          std::string, std::vector, etc... but it usually does not give you want you
          want for pointers. Your copied class will have it's pointers copied by
          value, pointing to the same things they were pointing to before. In some
          cases this may be what you want. In most cases it is not. One of the
          biggest dangers of this behavior is when the destructor of the class
          destroyes it's pointed to value (delete). Then your copied class may point
          to data that is no longer valid.

          Consider:

          class Foo
          {
          public:
          Foo() { MyData = new char[100]; }
          ~Foo() { delete[] MyData; }
          private:
          char* MyData;
          }

          If this class is copied, MyData will be copied by value, the pointer will be
          copied, and you will have 2 instances pointing to the same portion of
          memory, which is not what you want in most cases. Also, if the destructor
          ever gets invoked, such as a temporary being created and destroyed, then
          MyData will become invalid in the copied class. The normal way of dealing
          with this is with a copy constructor that assigns it's own memory.

          #include <algorithm>

          class Foo
          {
          public:
          Foo() { MyData = new char[100]; }
          ~Foo() { delete[] MyData; }
          Foo( const Foo& rhs )
          {
          MyData = new char[100];
          std::copy( &rhs.MyData[0], &rhs.MyData[99], MyData );
          }
          private:
          char* MyData;
          };

          --
          Jim Langston
          tazmaster@rocke tmail.com


          Comment

          • Jim Langston

            #6
            Re: default implementation of assignment operator

            Jim Langston wrote:
            Juha Nieminen wrote:
            >George2 wrote:
            >>I am wondering the default implementation of assignment operator
            >>(e.g. when we do not implement assignment operator in user defined
            >>class, what will be returned? temporary object? reference or const
            >>reference? deep copy or shallow copy is used in default assignment
            >>operator?)?
            >>
            > The compiler cannot automatically generate a deep-copying of the
            >objects because it has absolutely no way of knowing whether the
            >member pointers are pointing at memory allocated and owned by the
            >object itself, or whether they are just pointing to something else
            >(for example trying to deep-copy an element of a doubly-linked list
            >would be quite a bad idea).
            > The default assignment operator simply assigns each individual
            >member variable from the parameter to this, regardless of what it
            >is. If it's eg. a pointer, then a simple pointer assignment will be
            >done. In many cases the default assignment operator is ok, especially if
            >the class does not contain pointers.
            >>
            > It returns a const-reference to *this.
            >
            This behavior is sometimes refered to as a "bitwise copy" although
            that is not strictly true. If it was a bitwise copy, copying the
            bits of the class ignoring constructors, then there would be
            different values then there are.
            Basically it will take the base copy of whatever types are being
            copied. For most things this is fine. This will work for
            stl::containers , std::string, std::vector, etc... but it usually does
            not give you want you want for pointers. Your copied class will have
            it's pointers copied by value, pointing to the same things they were
            pointing to before. In some cases this may be what you want. In most
            cases it is not. One of the biggest dangers of this behavior is when
            the destructor of the class destroyes it's pointed to value (delete).
            Then your copied class may point to data that is no longer valid.
            >
            Consider:
            >
            class Foo
            {
            public:
            Foo() { MyData = new char[100]; }
            ~Foo() { delete[] MyData; }
            private:
            char* MyData;
            }
            >
            If this class is copied, MyData will be copied by value, the pointer
            will be copied, and you will have 2 instances pointing to the same
            portion of memory, which is not what you want in most cases. Also,
            if the destructor ever gets invoked, such as a temporary being
            created and destroyed, then MyData will become invalid in the copied
            class. The normal way of dealing with this is with a copy
            constructor that assigns it's own memory.
            #include <algorithm>
            >
            class Foo
            {
            public:
            Foo() { MyData = new char[100]; }
            ~Foo() { delete[] MyData; }
            Foo( const Foo& rhs )
            {
            MyData = new char[100];
            std::copy( &rhs.MyData[0], &rhs.MyData[99], MyData );
            }
            private:
            char* MyData;
            };
            A few things, this is the copy constructor, not the assignment operator.
            Both would need to be specified (see the rule of three). The assignment
            operator would look just about the same.
            Second,
            std::copy( &rhs.MyData[0], &rhs.MyData[99], MyData );
            probably needs to be
            std::copy( &rhs.MyData[0], &rhs.MyData[100], MyData );
            because it is my understanding that the end iterator needs to point 1 past
            the data.


            --
            Jim Langston
            tazmaster@rocke tmail.com


            Comment

            • Pete Becker

              #7
              Re: default implementation of assignment operator

              On 2007-12-15 13:30:40 -0500, "Jim Langston" <tazmaster@rock etmail.comsaid:
              Juha Nieminen wrote:
              >George2 wrote:
              >>I am wondering the default implementation of assignment operator
              >>(e.g. when we do not implement assignment operator in user defined
              >>class, what will be returned? temporary object? reference or const
              >>reference? deep copy or shallow copy is used in default assignment
              >>operator?)?
              >>
              >The compiler cannot automatically generate a deep-copying of the
              >objects because it has absolutely no way of knowing whether the member
              >pointers are pointing at memory allocated and owned by the object
              >itself, or whether they are just pointing to something else (for
              >example trying to deep-copy an element of a doubly-linked list would
              >be quite a bad idea).
              >The default assignment operator simply assigns each individual member
              >variable from the parameter to this, regardless of what it is. If it's
              >eg. a pointer, then a simple pointer assignment will be done.
              >>
              >In many cases the default assignment operator is ok, especially if
              >the class does not contain pointers.
              >>
              >It returns a const-reference to *this.
              >
              This behavior is sometimes refered to as a "bitwise copy" although that is
              not strictly true. If it was a bitwise copy, copying the bits of the class
              ignoring constructors, then there would be different values then there are.
              >
              That's a bit confusing, because of dangling references. So here's the
              deal: the compiler-generated assignment operator does member-by-member
              assignment, not bitwise assignment. Bitwise assignment copies the bits
              (think memcpy). Member-by-member assignment uses each type's assignment
              operator, and bitwise copying for builtin types.

              --
              Pete
              Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
              Standard C++ Library Extensions: a Tutorial and Reference
              (www.petebecker.com/tr1book)

              Comment

              • Juha Nieminen

                #8
                Re: default implementation of assignment operator

                Abhishek Padmanabh wrote:
                > It returns a const-reference to *this.
                >
                Not a const reference.
                You mean it's possible, when default assignment operators are used, to
                do this: (a = b) = c; ?

                I think I'm pretty sure it's not, even without trying.

                Comment

                • Pete Becker

                  #9
                  Re: default implementation of assignment operator

                  On 2007-12-15 16:32:57 -0500, Juha Nieminen <nospam@thanks. invalidsaid:
                  Abhishek Padmanabh wrote:
                  >>It returns a const-reference to *this.
                  >>
                  >Not a const reference.
                  >
                  You mean it's possible, when default assignment operators are used, to
                  do this: (a = b) = c; ?
                  >
                  I think I'm pretty sure it's not, even without trying.
                  Are you still sure after trying it?

                  --
                  Pete
                  Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
                  Standard C++ Library Extensions: a Tutorial and Reference
                  (www.petebecker.com/tr1book)

                  Comment

                  • Tadeusz B. Kopec

                    #10
                    Re: default implementation of assignment operator

                    On Sat, 15 Dec 2007 10:30:40 -0800, Jim Langston wrote:
                    Juha Nieminen wrote:
                    >George2 wrote:
                    >>I am wondering the default implementation of assignment operator (e.g.
                    >>when we do not implement assignment operator in user defined class,
                    >>what will be returned? temporary object? reference or const reference?
                    >>deep copy or shallow copy is used in default assignment operator?)?
                    >>
                    > The compiler cannot automatically generate a deep-copying of the
                    >objects because it has absolutely no way of knowing whether the member
                    >pointers are pointing at memory allocated and owned by the object
                    >itself, or whether they are just pointing to something else (for
                    >example trying to deep-copy an element of a doubly-linked list would be
                    >quite a bad idea).
                    > The default assignment operator simply assigns each individual member
                    >variable from the parameter to this, regardless of what it is. If it's
                    >eg. a pointer, then a simple pointer assignment will be done.
                    >>
                    > In many cases the default assignment operator is ok, especially if
                    >the class does not contain pointers.
                    >>
                    > It returns a const-reference to *this.
                    >
                    This behavior is sometimes refered to as a "bitwise copy" although that
                    is not strictly true. If it was a bitwise copy, copying the bits of the
                    class ignoring constructors, then there would be different values then
                    there are.
                    >
                    Basically it will take the base copy of whatever types are being copied.
                    For most things this is fine. This will work for stl::containers ,
                    std::string, std::vector, etc... but it usually does not give you want
                    you want for pointers. Your copied class will have it's pointers copied
                    by value, pointing to the same things they were pointing to before. In
                    some cases this may be what you want. In most cases it is not. One of
                    the biggest dangers of this behavior is when the destructor of the class
                    destroyes it's pointed to value (delete). Then your copied class may
                    point to data that is no longer valid.
                    Well, generally if an object owns some pointers, they should be wrapped
                    in some std::auto_ptr, boost::scoped_p tr or something like this.
                    Otherwise you loose exception safety and gain many headaches. OTOH
                    compiler generated assignment operator for class with std::auto_ptr is
                    even more surprising, so I recommend const std::auto_ptr.

                    --
                    Tadeusz B. Kopec (tkopec@NOSPAMP LEASElife.pl)
                    <casMercury: gpm isn't a very good web browser. fix it.

                    Comment

                    Working...