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
}