home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / cplus / 20037 < prev    next >
Encoding:
Text File  |  1993-01-28  |  2.1 KB  |  76 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!taumet!steve
  3. From: steve@taumet.com (Steve Clamage)
  4. Subject: Re: operator = with inheritance
  5. Message-ID: <1993Jan28.184836.27790@taumet.com>
  6. Organization: TauMetric Corporation
  7. References: <1993Jan14.185649.21213@murdoch.acc.Virginia.EDU> <1993Jan26.175530.1382@PacBell.COM>
  8. Date: Thu, 28 Jan 1993 18:48:36 GMT
  9. Lines: 65
  10.  
  11. pjcondi@ns.pacbell.com (Paul Condie) writes:
  12.  
  13. >class A {
  14. >   public:
  15. >    ...
  16. >    virtual A & operator = (const A & rhs) {
  17. >        a = rhs.a;
  18. >        return *this;
  19. >    }
  20. >   private:
  21. >    int a;
  22. >};
  23.  
  24.  
  25. >class B : public A {
  26. >   public:
  27. >    ...
  28. >    A & operator = (const A & rhs) {
  29. >        A::operator = (rhs);
  30. >        // The following cast should be ok because we know
  31. >        // we have a B object because the virtual mechanism
  32. >        // has told us. right?
  33. >        b = ((B &)rhs).b;
  34. >        return *this;
  35. >    }
  36. >   private:
  37. >    int b;
  38. >};
  39.  
  40. The assumption in the comment is wrong.  Suppose we write
  41.     A x;
  42.     B y;
  43.     ...
  44.     y = x;
  45. We will get
  46.     y.B::operator=(x);
  47. The function assumes incorrectly that its argument is a B, but it is
  48. really an A.
  49.  
  50. Secondly, an unrelated point.  It is not a very good idea to call A::op=
  51. explicitly in B::op=, since a B member function now depends on the
  52. details of the A class.  For example, the op= in A might be removed
  53. on the grounds it does exactly what the default version would do.  The
  54. B::op= function will no longer compile.
  55.  
  56. You usually want to invoke the base class op= implicitly, so that you
  57. can get the compiler-generated version if that's all there is.  Here
  58. is a schema for the op= of a derived class.
  59.  
  60.     B& B::operator=(const B& rhs) {
  61.         if( this != &rhs ) {    // don't forget this test!
  62.         (A&)(*this) = (A&)rhs;    // invoke base class op= implicitly
  63.         ... // assign to the members specific to class B
  64.         }
  65.         return *this;
  66.     }
  67. Unless the base classes have some perverse design, this will always
  68. do the right thing.
  69.  
  70. You can write an additional op= which takes an A&, using the same
  71. schema.  Of course, you can't assign from the B parts of the rhs, since
  72. it doesn't have any.  You will have to initialize them some other way.
  73. -- 
  74.  
  75. Steve Clamage, TauMetric Corp, steve@taumet.com
  76.