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 }