cotner@brahms.berkeley.edu (Carl Cotner) (10/28/89)
I'm a beginner to C++ as well as to this newsgroup, so please bear with me
if what I'm asking seems trite and trivial. I don't have the hang of
programming in an object-oriented manner yet, but I'm trying.
What I would like to do is define a class called Number which can
automatically perform operations (+,-,*,/) on several types and convert
to and from each one transparently. Sound like a familiar problem?
(Then why am I having so much trouble implementing it!)
My goal in the end is to develop numerical analysis programs in which I
define functions that use this class, like so:
Number func1(Number &x)
{
Number y = 1/(x*x + 1);
return y;
}
Now it shouldn't matter whether I pass in a real, complex, int, double, or
rational represented within Number. The Number object y performs the
operations and type conversions automatically. If Number x had originally
contained an int, a double would have been returned. If x were a complex
int, then a complex double should be expected.
The types that I would like to be represented are:
int, double, complex int (both real and imaginary parts are int's),
complex double, and rational (representing numerator and
denominator as 2 ints's)
and perhaps keep the door open for future types such as quad and complex
quad.
Okay how do I do this?
My first impulse was to define each type as a separate class and have
Number contain a pointer to them.
enum { INT=0, DBL, CINT, CDBL, RAT } Ntype;
class NumObj {
Ntype NumType; //this is just the base class
public:
void setType(nt) { NumType = nt; }
Ntype getType() { return NumType; }
virtual void print() { cerr << "print should be bound\n"; }
virtual void getnval(void **num)
{ cerr << "getnval should be bound\n"; }
virtual void setnval(const void *num)
{ cerr << "setnval should be bound\n"; }
}
// We then derive a new class to represent each type
class Int : public NumObj {
int a;
public:
Int() { setType(INT); }
Int(int v) : a(v) { setType(INT); }
void getnval(void **num) { *num = new int;
*(int *)*num = a; }
void setnval(void *num) { a = *(int *)num; }
void print() { cerr << a << "\n"; }
operator Int +(const CInt& B) { return Int(a + B.a); }
}
// Similarly we have the rest of the types
class Cdbl : public NumObj {
double u,v;
public:
Cdbl(double u, double v) : a(u), b(v) { setType(CDBL); }
...
}
Then Number class would then be
class Number {
NumObj *Nptr; // pointer to base class for each type
public:
Number(int a) { Nptr = new Int; Nptr->setval( a ); }
Number(double a, double b) { Nptr = new Cdbl;
Nptr->setval(a,b); }
void print() { cout << "Number = "; Nptr->print(); }
friend Number operator +(Number &A, Number &B);
}
The getnval()/setnval() routines are used for passing data to and from
each of the types using a consistent prototype; typically one would do
something like this to convert from int to double:
void *val;
Nptr->getnval( &val ); // get say an int
// now perform conversion
double newval = double( *(int *)val );
val = newval;
setnval( &val );
Form here on, I start becoming confused and dazed as I try to define and
implement the conversion routines between each separate type class and
Number, as well as define the binary operations + - * /.
About the onlything that works is print().
Nptr->print();
works just fine.
How should I go about setting up this class? I've tried several
attempts but I just seem to end up with awkward code.
One final question: Assuming this Number class works and is the right way
to go, I would like to start writing up routines such as
NewtonRaphson( Number(*function)(), Point StartPt )
{
}
Ie, have a generic numerical technique, as one would have a generic
stack or queue.
My question, is this also the correct way to go about it? That is,
should I be passing in a pointer to a function, or should I set up
NewtonRaphson as a class, declare a virtual function which I then
define at run-time?
From the gist of these questions you may deduce that I still have a lot
to learn about C++ and OOPS. Any suggestions for how I can become better
educated?
Thanks
Carl
cotner@brahms.Berkeley.EDU
ucbvax!brahms!cotner Carl Cotner/UCB Math Dept/Berkeley CA 94720