[comp.lang.c++] More Questions on operator=

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

In article <863@ethz.UUCP>, I posed a question concerning the
inheritance of operator=.  Essentially, cfront 1.2.1 produced the
error message indicated by <<<<< :

class Base { public:
  int data;
  Base& operator=(Base& another) { data = another.data; return *this; }
  void foo() { ++data; }
};

class Derived : public Base { public:
  Derived() { data = 0; }
};

main() {
  Derived d, d1, d2;
  d.foo();
  d = d1;  	// <<<<< error: assignment not defined for class Derived
  d.operator=(d2);
}

Since the C++ bible states on p.265 that for a binary operator @,
x @ y can be interpreted as x.operator@(y), and since member functions
are inherited by a derived class, the error message seemed like a bug
to me.

However, as Clifford Beshers of Columbia kindly pointed out to me,
the bible also says that assignment is not implicitly defined for
objects of a class derived from a class for which operator= has been
defined p.277).  Now, if you accept this restriction (which I have
a very hard time to do, but I guess I don't have much of a choice!),
the above example should actually produce TWO errors instead of one,
because d.operator=(d2) seems "just as wrong" as d = d1, since
d = d1 is interpreted as d.operator=(d1) anyway.

Clarifications on the topic, anyone?  (I do hope the silly restriction
is lifted in 2.0!)


On a related issue, what is the approved way to get the default
behaviour of assignment (ie., bitwise copying) INSIDE the definition
of a user-defined operator=?  (I need to do this to make sure that
an invisible _vptr field is alway copied along with all data members.)
::operator=(*this, another) does not work (why?), so I currently use
bcopy((char*)&another, (char*)this, sizeof(Object)) instead, e.g.

Object& operator=(Object& another)
{
  // do some stuff (e.g., manipulating reference counts)
  bcopy((char*)&another, (char*)this, sizeof(Object));  // copy EVERYTHING
  // do some more stuff
  return *this;
}

-- 
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 <925@ethz.UUCP> marti@ethz.UUCP (Robert Marti) writes:
>
>
>On a related issue, what is the approved way to get the default
>behaviour of assignment (ie., bitwise copying) INSIDE the definition
>of a user-defined operator=?  

No. And in 2.0 the default behavior never copies the _vptr. The _vptr
is associated with an object when the object is allocated and cannot
be changed. Copying the _vptr "breaks" the C++ type system.

Consider something like

	class B {
		virtual void f() { }
		} ;

	class D : class B 
		int x ;
		void  f() { x = 99 ; }
		} ;

	void g() {
		B b ;
		D d ;
		b = d ;  // legal because D is derived from B.
		b.f() ;
			// If the vptr has been copied then this
			// call will be nonense, b has no x member
			// for f to store 99 in.
		} 

>(I need to do this to make sure that
>an invisible _vptr field is alway copied along with all data members.)
>::operator=(*this, another) does not work (why?), so I currently use
>bcopy((char*)&another, (char*)this, sizeof(Object)) instead, e.g.
>

bcopy (or the ANSI equivalent memcpy) is the appropriate way to do
this operation.  Just be sure you know what you're doing when you
circumvent the type system this way.


>Object& operator=(Object& another)
>{
>  // do some stuff (e.g., manipulating reference counts)
>  bcopy((char*)&another, (char*)this, sizeof(Object));  // copy EVERYTHING
>  // do some more stuff
>  return *this;
>}

This example doesn't look like an appropriate use. It is subject to
the same "bug" as my earlier example. What if the "another" was
allocated as a D (where D is a class derived from Object)?

Jerry Schwarz
AT&T Bell Labs, Murray Hill

jima@hplsla.HP.COM (Jim Adcock) (05/20/89)

As per Marti's example, I don't understand why the language
forces redefinition of op= when a derived class doesn't have
any new members?

Can anyone explain the logic in this?