[gnu.g++.help] problem with inherited overloaded operators

amante%asgard@HUB.UCSB.EDU (05/31/91)

I have some questions on how to make derived class operators to work
properly. As a backround, I have a specialized vector class (VEC4)
which has an array of 4 floats as member data. I overloaded operators
to work on the member data of this class. For example
	VEC4& operator+(VEC4&);
Now I have an application which has a lot in common with VEC4 which
I call QUAT (short for quaternions). The natural thing for me to do
was to derive QUAT from VEC4 and just redefine the operators which
differ. So I was expecting to inherit the operator+() from VEC4 and
just use it for QUAT. But when I declare QUATs and use the operator+()
(see main() below) I get compile-time errors as follows:
(I'm using g++ v1.37.1 running on a SUN4 with SUN OS 4.0)

______________________________________________________________________
[shogun:/home/shogun/ra/amante/DATACLASS]>!g+
g++ -O -v t.cc -lm
g++ version 1.37.1 (based on GCC 1.37)
 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ t.cc /usr/tmp/cca21925.cpp
GNU CPP version 1.37.1
 /usr/local/lib/gcc-cc1plus /usr/tmp/cca21925.cpp -quiet -dumpbase t.cc -O -version -o /usr/tmp/cca21925.s
GNU C++ version 1.37.1 (based on GCC 1.37) (sparc) compiled by GNU C version 1.37.1.
default target switches: -mfpu -mepilogue
t.cc: In function int main ():
t.cc:71: conversion between incompatible aggregate types requested
______________________________________________________________________

From what I gather, the VEC4::operator+() is used, allowing QUAT
arguments in place of VEC4 arguments, *but* the return value is
of type VEC4 which conflicts that of the lhs (in this case a QUAT).
So I defined a constructor
	QUAT(VEC4&)
which takes in a VEC4 as an argument and returns a QUAT. This
in effect allows the assignment of a base class instance to a derived
class instance (which is not normally allowed in C++). When this
constructor is defined program compiles successfully and produces the
expected results.

Here are my questions:
(1) Is there anything illegal (in terms of C++) when I defined the constructor?
(2) If it is, is there a way of making inherited overloaded operators to
    work?

Following is the test case:
______________________________________________________________________
#include <math.h>

/////////////////////////////////////////////////////////
/////  This is the class which defines 3-D vectors  /////
/////////////////////////////////////////////////////////

class VEC3 {

public:
  float s[3];

  VEC3(float a = 0.0, float b = 0.0, float c = 0.0)
  {s[0] = a; s[1] = b; s[2] = c;}

  VEC3& operator + (VEC3& b)
  { return VEC3(s[0] + b.s[0], s[1] + b.s[1], s[2] + b.s[2]); }

  friend VEC3& operator * (float a, VEC3& b)
  { return VEC3(a * b.s[0], a * b.s[1], a * b.s[2]); }
};

/////////////////////////////////////////////////////////
/////	This class is for 4-element vectors	    /////
/////////////////////////////////////////////////////////

class VEC4 {

  public:
    VEC3 v;  float s;

  VEC4(VEC3& x = VEC3(0.0, 0.0, 0.0), float y = 0.0) : v(x), s(y) {};

  VEC4& operator + (VEC4& b)
  { return VEC4(v + b.v, s + b.s); }
};

/////////////////////////////////////////////////////////
/////	This class is for Quaternions		    /////
/////////////////////////////////////////////////////////

class QUAT : public VEC4
{

#ifdef WORKS
  // Is the following constructor legal C++?
  // Note it allows a base class instance to be assigned to a
  //	derived class instance.
  QUAT(VEC4& q)			// to allow inherited operator@'s
  { s = q.s; v = q.v; }
#endif

public:
//  VEC3v; float s;             // inherited from VEC4

  QUAT(VEC3& rot_axis = VEC3(0.0, 0.0, 0.0), float theta = 0.0)
  { float theta2 = 0.5*theta;
    s = cos(theta2);
    v = sin(theta2)*rot_axis;
  }

//  QUAT& operator+(QUAT&);	// inherited from VEC4
};

/////////////////////////////////////////////////////////
/////	This is the main program		    /////
/////////////////////////////////////////////////////////

main()
{ QUAT a, b, c;
  a = b+c;		// this gives error when the constructor
			// QUAT(VEC4& q) is not defined
}