[comp.lang.c++] "Inheritance" of operator=

marti@ethz.UUCP (Robert Marti) (05/10/89)

Disclaimer:  I am fairly new at trying out some things in C++, so don't
flame me if I overlooked something obvious.

The following code gives an error on the line indicated with <<<<< when
compiled on a Sun-3/50, SunOS 4.0.1, with cfront 1.2.1.

=====
struct ObjDescr {
  void* val;
  int ref_count;
};

class Object {
protected:
  ObjDescr* obj;
public:
  Object();
  Object(Object& another);
  void operator=(Object& another);
  virtual ~Object();
  virtual int operator==(Object& another);
};

class IntObj : public Object {
public:
  IntObj();
  IntObj(int i);
  int operator==(Object& another);
  operator Object();
};

// definitions of Object:: and IntObj:: member functions ...

main()
{
  IntObj o;
  IntObj o1 = 1;
  IntObj o2 = 2;

  o = o1;  // <<<<< error: assignment not defined for class IntObj
  o.operator=(o2);
}
=====

Why is this?  The "bible" somewhere states that x operator@ y
is equivalent (among other things) to x.operator@(y), so I feel
that cfront should figure out in both cases that I want the
"inherited" member function Object::operator= for the IntObj o ...

-- 
Robert Marti                      Phone:      +41 1 256 52 36
Institut fur Informationssysteme
ETH-Zentrum                       CSNET/ARPA: marti%inf.ethz.ch@relay.cs.net
CH-8092 Zurich, Switzerland       UUCP:       ...uunet!mcvax!ethz!marti

jss@hector.UUCP (Jerry Schwarz) (05/11/89)

In article <863@ethz.UUCP> marti@ethz.UUCP (Robert Marti) asks
some questions about inheritance of assignment.

Assignment is special because it is defined for all classes, (thus it
never needs to be inherited).

But the meaning of assignment has changed between 1.2 and 2.0. In 1.2
the synthesized assignment operator was always "bitwise copy".  This
was seen to be wrong and in 2.0 assignment is defined to be
"recursive".

The example is something like

struct B {
	// some data members
	B& operator=(B&) ;
} ; 

struct D : public B {
	// some more data members
} ;

void f()
{
	D d1, d2 ;
	d1 = d2 ;	// what should happen here?
	}

Note that it doesn't make much sense to just "inherit" assignment
because that would mean that the added members of D wouldn't
participate in assignment of D.  Since 1.2 didn't implement a
"recursive" assignment, and a bitwise copy would clearly be wrong. It
insisted that if assignment was defined in the base class that it
also be defined in the derived class.

In 2.0 the synthesized assignment operation usually "does the right
thing" so this restriction is not imposed.

Jerry Schwarz
AT&T Bell Labs, Murray Hill

marti@ethz.UUCP (Robert Marti) (05/17/89)

In article <11519@ulysses.homer.nj.att.com>, jss@hector.UUCP (Jerry Schwarz)
writes:
> Assignment is special because it is defined for all classes, (thus it
> never needs to be inherited).
> 
> But the meaning of assignment has changed between 1.2 and 2.0. In 1.2
> the synthesized assignment operator was always "bitwise copy".  This
> was seen to be wrong and in 2.0 assignment is defined to be
> "recursive".

I am glad to hear that the semantics of (user-defined) assignment has
changed in 2.0, although I am not quite sure what you mean when you say
that it is defined to be "recursive".  Could you elaborate on that?


> Note that it doesn't make much sense to just "inherit" assignment
> because that would mean that the added members of D wouldn't
> participate in assignment of D.  Since 1.2 didn't implement a
> "recursive" assignment, and a bitwise copy would clearly be wrong.
                          ^^^^^
                          seems superfluous to me(?)

Well, in my example, no additional data members were defined in the
derived class, so bitwise copy would definitely make sense!

-- 
Robert Marti                      Phone:      +41 1 256 52 36
Institut fur Informationssysteme
ETH-Zentrum                       CSNET/ARPA: marti%inf.ethz.ch@relay.cs.net
CH-8092 Zurich, Switzerland       UUCP:       ...uunet!mcvax!ethz!marti

jss@hector.UUCP (Jerry Schwarz) (05/19/89)

In article <933@ethz.UUCP> marti@ethz.UUCP (Robert Marti) writes:
>In article <11519@ulysses.homer.nj.att.com>, jss@hector.UUCP (Jerry Schwarz)
>writes:
>
>I am glad to hear that the semantics of (user-defined) assignment has
>changed in 2.0, although I am not quite sure what you mean when you say
>that it is defined to be "recursive".  Could you elaborate on that?
>

The semantics of user-defined assignment has not changed.  It remains
that you call the user-defined function.  Its the semantics of
builtin assignment on classes that has changed.

Assignment for a class K means to assign each "part" of K according
(recursively) to the appropriate definition of assignment for that
part.  A part is either a member declared as a member of K or
the parts of K that result from inheritance. 

For example.

        class K {
        public:
                K& operator=(const K&) ;
        } ;

        class B {
        private:
                int b ;
        protected:
                virtual void f() ;
                B& operator=(const B&) ;
        } ;

        class D : public B {
                K k ;
                int x ;
                } 

        D d1, d2 ;

	// The "parts" of d1 are d1.k, d1.x (B&)d1

        d1 = d2 ; 
                // copy d2.x to d1.x call K::operator= to "assign"
                // d2.k to d1.k.  And call B::operator= to "assign"
                // the base part of d2 to the base part of d1.
		// The vtable pointer is not copied.


Jerry Schwarz
AT&T Bell Labs, Murray Hill