A Polynomial Template Class A Polynomial Template Class

The problem

To develop a class to represent polynomials. (For our simplified purpose this is something of the form

something x2 + something x + something

The somethings are what we call coefficients.

We would like both ints and strings to serve as coefficients. That is we would like to have polynomials that look like 2x2 + 3x + 4 and polynomials that look like ax2 + bx + c.

Also, we should be able to add polynomials with + and get something that looks reasonable.

And by default, a polynomial should look like 0x2 + 0x + 0 no matter what kind of coefficients (int or string) it has.

One solution:

I make a poly template class. The default constructor sets the coefficients to zero. The trouble is that zero for an int is 0, but zero for a string is "0".

One way to handle this is as follows:

Static constants

A static constant is a constant that belongs to the class and not objects of the class.

The ZERO constant in the Int class is set up by the line static int ZERO; in the public section of the class. The ZERO constant in the String class is set up by the line static string ZERO; int the public section of the String class.

The static ZERO constant in the Int class is set by the line int Int::ZERO = 0; and the static ZERO constant in the String class is set by the line string String::ZERO = ""; in the coefficients.cpp file.

The ZERO constants I define in the Int and String classes are invoked by the statements Int.ZERO and String.ZERO in the places they are used.

The main program that uses the whole works

The file polyMain.cpp:

#include <iostream>

#include "coefficients.h"
#include "poly.h"

using namespace std;

int main ()
{
   //Set up three Int type polynomials.
   
   poly <Int> one, two (1,2,3), three (3,4,6);
   
   cout << one          << endl;
   cout << two          << endl;
   cout << three        << endl;
   cout << two + three  << endl;
   
   //Set up three String type polynomials.
   
   poly <String> four ("a","b","c"), five ("A","B","C"), six;
   
   cout << four         << endl;
   cout << five         << endl;
   cout << four + five  << endl;
   
   cout << six << endl;
   
   return 0;
}

The wrapper classes Int and String in the file coefficients.h:

The file coefficients.h:

#ifndef COEFFICIENT_H
#define COEFFICIENT_H

#include <iostream>
#include <string>

using namespace std;

class Int
{
   friend ostream& operator<< (ostream&, Int& anInt);
   friend Int      operator+  (Int& one, Int& two);
   
public:
   Int (int n = 0);         //If no arguments then n is set to 0
   Int (Int&);
   
   Int& operator= (int);
   
   static int ZERO;         //ZERO belongs to the class not to objects
   
private:
   int val;
};

class String
{
   friend ostream& operator<< (ostream&, String&);
   friend String   operator+  (String& one&, String& two);
   
public:
   String (string n = "");        //If no arguments then n gets ""
   String (String&);             
   String (char []);              //For handling C strings
   
   String& operator= (String&);
   
   static string ZERO;            //ZERO belongs to the class not to objects
   
private:
   string val;
};

#endif

The functions file for Int and String

The file coefficients.cpp:

//First the particulars for the Int class

//Initialization of the static constant ZERO

int Int::ZERO = 0;

Int::Int (int n)
{
   val = n;
}

Int::Int (Int& aInt)
{
   val = aInt.val;
}

Int& Int::operator= (Int& aInt)
{
   val = aInt.val;
   
   return *this;
}

ostream& operator<< (ostream& out, Int& aInt)
{
   out << aInt.val;
   
   return out;
}

Int operator+ (Int& one, Int& two)
{
   Int temp (one.val + two.val);
   
   return temp;
}

//Now the particulars for the String class

//Initialization of the static constant ZERO

string String::ZERO = "0";

String::String (string& astring)
{
   val = aString;
}

String::String (String& aString)
{
   val = aString.val;
}

String::String (char array [])
{
   val = array;
}

String& operator= (String& aString)
{
   val = aString.val;
   
   return *this;
}

ostream& operator<< (ostream& out, String& aString)
{
   out << aString.val;
   
   return out;
}

String operator+ (String& one, String& two)
{
   String temp (one.val + two.val);
   
   return temp;
}

The poly template class

Finally, the file poly.h that defines the polynomial template class. Notice that the class definition and the functions all go together in one file when you make a template.

You will notice that the operator<< and operator+ function are not friends of the class for a change. It seems that friends can be problematic in templates. To get around this problem I provide public functions to access the data of the class.

#ifndef POLY_H
#define POLY_H

template<class T>
class poly
{
public:
   poly ();                             //Default gives 0 coefficients
   poly (const T&, const T&, const T&);
   poly (poly<T>&);
   
   poly<T>& operator= (poly<T>&);
   
   T getOne   ();     //Functions needed to make operator<< and operator+ work
   T getTwo   ();
   T getThree ();

private:
   T one;
   T two;
   T three;
};

template<class T>
poly<T>::poly ()
{
   one   = T.ZERO;    //Calls the ZERO constant of the T class: Int or String
   two   = T.ZERO;
   three = T.ZERO;
}

template<class T>
poly<T>::poly (const T& A, const T& B, const T& C)
{
   one   = A;
   two   = B;
   three = C;
}

template<class T>
poly<T>::poly (poly<T>& aPoly)
{
   one   = aPoly.one;
   two   = aPoly.two;
   three = aPoly.three;
}

template<class T>
poly<T>& poly<T>::operator= (poly<T>& it)
{
   one   = it.one;
   two   = it.two;
   three = it.three;
   
   return *this;
}

template<class T>
T poly<T>::getOne ()
{
   return one;
}

template<class T>
T poly<T>::getTwo ()
{
   return two;
}

template<class T>
T poly<T>::getThree ()
{
   return three;
}

template<class T>
ostream& operator<< (ostream& out, poly<T>& it)
{
   T one   = it.getOne ();
   T two   = it.getTwo ();
   T three = it.getThree ();
   
   out << one << "x^2 + " << two << "x + " << three << endl;
   
   return out;
}

template<class T>
poly<T> operator+ (poly<T>& first, poly<T>& second)
{
   T newOne   = first.getOne   () + second.getOne   ();
   T newTwo   = first.getTwo   () + second.getTwo   ();
   T newThree = first.getThree () + second.getThree ();
   
   poly<T> temp (newOne, newTwo, newThree);
   
   return temp;
}

#endif


File translated from TEX by TTH, version 2.25.
On 7 Oct 2002, 18:08.