home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / cplus / 13610 < prev    next >
Encoding:
Internet Message Format  |  1992-09-14  |  4.5 KB

  1. Path: sparky!uunet!pmafire!news.dell.com!swrinde!sdd.hp.com!ux1.cso.uiuc.edu!m.cs.uiuc.edu!sunb10.cs.uiuc.edu!sparc10.cs.uiuc.edu!pjl
  2. From: pjl@sparc10.cs.uiuc.edu (Paul Lucas)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Default assignment semantics
  5. Message-ID: <1992Sep14.152055.5825@sunb10.cs.uiuc.edu>
  6. Date: 14 Sep 92 15:20:55 GMT
  7. References: <BuJs8K.Hzr@vcd.hp.com>
  8. Sender: news@sunb10.cs.uiuc.edu
  9. Distribution: usa
  10. Organization: University of Illinois at Urbana-Champaign
  11. Lines: 96
  12.  
  13. In <BuJs8K.Hzr@vcd.hp.com> John Matthews <jm@vcd.hp.com> writes:
  14.  
  15. >As I understand it, if a class does not have an explicitly defined
  16. >assignment operator, a default assignment operator is generated
  17. >by the compiler. This default operator simply does a member-wise
  18. >assignment. As has been pointed out many times, these semantics
  19. >are dangerous for classes that have pointers to dynamically created
  20. >objects as fields.
  21.  
  22. *****>    What many people seem to have forgotten is that this is not a
  23.     new problem.  Assigning good ol' structures in C that contain
  24.     pointers is just as bad.  One has to write a copy function in
  25.     such cases because the default assignment doesn't work.
  26.  
  27. >It seems to me that a more robust default assignment operator would
  28. >have the following semantics:
  29.  
  30. >  1) Invoke the destructor of the object being assigned to.
  31. >  2) Invoke the copy constructor on the object being assigned
  32. >      to, taking as an argument the object being assigned from.
  33.  
  34. >In the case where a class has no user defined destructor or copy
  35. >constructor, the above semantics devolves to member-wise
  36. >assignment, just as before. However, for classes that have
  37. >user defined destructors and copy constructors, (as all classes
  38. >that have pointers to dynamic objects should) the above
  39. >semantics generates code that is much safer. Take for example a
  40. >String class, whose constructor allocates a character buffer for
  41. >a string, and whose destructor frees that buffer. The user-defined
  42. >copy constructor would construct its String object with a separately
  43. >allocated character buffer of the same size as its String argument,
  44. >and perform a string copy between the two character buffers.
  45.  
  46. *****>    Ah, but in some String classes, if the LHS's buffer is big
  47.     enough to contain the RHS's, then the buffer is not
  48.     deallocated.  BTW, some String classes use chunks of buffers of
  49.     a rounded-off size to lessen fragmentation.
  50.  
  51.     Also, chances are that someone who's writing a full-blown string
  52.     class won't forget to overload assignment; it's code is trivial
  53.     and is dwarfed by the remaining code.
  54.  
  55. >Under the current default assignment operator semantics, for every  
  56. >String assignment made, a character buffer is 'leaked', and two
  57. >pointers to the same buffer are made.
  58.  
  59. *****>    Not if the assignment operator is overloaded.
  60.  
  61. >Under the above semantics,
  62. >however, the assignee String first has its buffer deallocated, and
  63. >then recieves a new buffer from the copy constructor, just like you
  64. >would expect.
  65.  
  66. >Since this is not the semantics of the current assignment operator,
  67. >a user defined assignment operator needs to be defined whenever
  68. >a user defined destructor or copy constructor exists for a class.
  69.  
  70. *****>    Trivial.
  71.  
  72. >Thus what I want to do in most of my assignment operators is
  73. >explicitly invoke the corresponding destructor and copy constructor.
  74.  
  75. *****>    Ah..."most."  There are occasions, as I've already pointed out,
  76.     when one doesn't want the d'tor called.  To have this
  77.     flexibility is probably part of the reason the assignment
  78.     operator is as it is.
  79.  
  80. >I know how to explicitly call a destructor on an object, but how do
  81. >you explicitly call a copy constructor on what used to be an object?
  82. >The only way I know of to do this is to overload operator new() with a
  83. >pointer argument. The overloaded new() operator would just return
  84. >the pointer. I could then write an assignment operator like the following
  85. >for any class X:
  86.  
  87. >        X& X::operator=( const X& from )
  88. >        {
  89. >                  this->~X();                                   // invoke
  90. >destructor.
  91. >                  new(this) X(from);                       // invoke copy
  92. >constructor.
  93. >                  return( *this );
  94. >        }
  95.  
  96. >However overloading new seems a little kludgy when all I want to
  97. >do is call a constructor on a specific object reference.
  98.  
  99. *****>    Well, it still seems simpler to just overload the assigment
  100.     operator.
  101.  
  102.     Another case that comes to mind if reference-counting;
  103.     assignment operators for such classes do different things
  104.     altogether.
  105. -- 
  106.     - Paul J. Lucas                University of Illinois    
  107.       AT&T Bell Laboratories        at Urbana-Champaign
  108.       Naperville, IL            pjl@cs.uiuc.edu
  109.