Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Don't forget to read Tuesday's email newsletter for your chance to win a free copy of Construct 2!


Like
0Likes
Dislike

Introduction to Pointers, Structures and Linked-Lists Part 11

By Chris Bennett aka Dwarfsoft | Published Sep 30 2004 04:47 AM in General Programming

left new cexpression int class result delete right(null left(null
If you find this article contains errors or problems rendering it unreadable (missing images or files, mangled code, improper text formatting, etc) please contact the editor so corrections can be made. Thank you for helping us improve this resource



So now that we have had an introduction to Inheritance, we can start to look at what this allows us to do. To explain this I will start using more abstract themes. The way this concept was taught
to me was using math as an example in a reverse polish calculator (Feel free to look this up, as its interesting from a Finite State Machine and Scripting perspective).


So what we started with was an Equation was equal to some data (numbers) with operations used to transform them into a solution. Let us have a look at what we need from our base class of
cExpression.



<span class="codekeyword">class</span> cExpression

{

<span class="codekeyword">public:</span> 

   <span class="codekeyword">virtual int</span> Evaluate()=0;

};


Welcome to the virtual keyword. our cExpression class has become an abstract base class, so lets find out why. More importantly lets find out what is meant by an abstract base class.


Abstraction in this sense is not exactly the same as when I was talking about data abstraction. Here by abstraction we basically are saying cExpression is defining how its child classes will
operate, but it itself does not actually do anything. Think of an abstract base class as a framework for future classes. Now, on to the inheritance.



<span class="codekeyword">class</span> cConstant : <span class="codekeyword">public</span> cExpression

{

<span class="codekeyword">public</span>: 

   cConstant(<span class="codekeyword">int</span> NewValue)

   {

      value = NewValue;

   }



   <span class="codekeyword">int</span> Evaluate()

   {

      <span class="codekeyword">return</span> value;

   } 

   <span class="codekeyword">void</span> Set(<span class="codekeyword">int</span> val)

   {

      value = val;

   }

<span class="codekeyword">private</span>:

   <span class="codekeyword">int</span> value;

};


Not coming together yet? Well, we are not yet halfway there.



<span class="codekeyword">class</span> cAddition : <span class="codekeyword">public</span> cExpression

{

<span class="codekeyword">public</span>:

   cAddition(cExpression *left, cExpression *right) : Left(NULL), Right(NULL)

   {

      Left = left;

      Right = right;

   }

   cAddition(<span class="codekeyword">int</span> left, <span class="codekeyword">int</span> right) : Left(NULL), Right(NULL)

   {

      Left = <span class="codekeyword">new</span> cConstant(left);

      Right = <span class="codekeyword">new</span> cConstant(right);

   }

   ~cAddition()

   {

      <span class="codekeyword">if</span> (Left) <span class="codekeyword">delete</span> Left;

      <span class="codekeyword">if</span> (Right) <span class="codekeyword">delete</span> Right;

   }

   <span class="codekeyword">int</span> Evaluate()

   {

      <span class="codekeyword">int</span> Result = 0;

      <span class="codekeyword">if</span> (Left) Result = Left->Evaluate();

      <span class="codekeyword">if</span> (Right) Result += Right->Evaluate();

      <span class="codekeyword">return</span> Result;

   } 

<span class="codekeyword">private</span>: 

   cExpression * Left,* Right;

};


What we are setting up here is a method of being able to use each class (the base class tells us how to access each classes members) without having to know what kind of class we have. When looking
at only two classes this is hard to appreciate as useful, but I will start explaining alternatives soon, and then it will become apparent as to how useful this method of using classes can actually
be.



<span class="codekeyword">class</span> cMultiplication : <span class="codekeyword">public</span> cExpression

{

<span class="codekeyword">public</span>:

   cMultiplication(cExpression *left, cExpression *right) : Left(NULL), Right(NULL)

   {

      Left = left;

      Right = right;

   }

   cMultiplication(<span class="codekeyword">int</span> left, <span class="codekeyword">int</span> right) : Left(NULL), Right(NULL)

   {

      Left = <span class="codekeyword">new</span> cConstant(left);

      Right = <span class="codekeyword">new</span> cConstant(right);

   }

   ~cMultiplication()

   {

      <span class="codekeyword">if</span> (Left) <span class="codekeyword">delete</span> Left;

      <span class="codekeyword">if</span> (Right) <span class="codekeyword">delete</span> Right;

   } 

   <span class="codekeyword">int</span> Evaluate()

   {

      <span class="codekeyword">int</span> Result = 0;

      <span class="codekeyword">if</span> (Left) Result = Left->Evaluate();

      <span class="codekeyword">if</span> (Right) Result *= Right->Evaluate();

      <span class="codekeyword">return</span> Result;

   } 

<span class="codekeyword">private</span>: 

   cExpression * Left,* Right;

};





<span class="codekeyword">class</span> cDivision : <span class="codekeyword">public</span> cExpression

{

<span class="codekeyword">public</span>:

   cDivision(cExpression *left, cExpression *right) : Left(NULL), Right(NULL)

   {

      Left = left;

      Right = right;

   }

   cDivision(<span class="codekeyword">int</span> left, <span class="codekeyword">int</span> right) : Left(NULL), Right(NULL)

   {

      Left = <span class="codekeyword">new</span> cConstant(left);

      Right = <span class="codekeyword">new</span> cConstant(right);

   }

   ~cDivision()

   {

      <span class="codekeyword">if</span> (Left) <span class="codekeyword">delete</span> Left;

      <span class="codekeyword">if</span> (Right) <span class="codekeyword">delete</span> Right;

   } 

   <span class="codekeyword">int</span> Evaluate()

   {

      <span class="codekeyword">int</span> Result = 0;

      <span class="codekeyword">int</span> temp = 0;

      <span class="codekeyword">int</span> div = 0;

      <span class="codekeyword">if</span> (Left) temp = Left->Evaluate();

      <span class="codekeyword">if</span> (Right)

      {

         div = Right->Evaluate();

         <span class="codecomment">// Calculate the integer Division</span>

         <span class="codekeyword">while</span> ((temp >= div) && div)

         { 

            temp-=div;

            ++Result;

         }

         <span class="codecomment">// Round Up if we have to</span>

         <span class="codekeyword">if</span> (temp >= (div-temp))

            ++Result; 

      } <span class="codekeyword">else </span>

         Result = 0;

      <span class="codekeyword">return</span> Result;

   } 

<span class="codekeyword">private</span>: 

   cExpression * Left,* Right;

};





<span class="codekeyword">class</span> cSubtraction : <span class="codekeyword">public</span> cExpression

{

<span class="codekeyword">public</span>:

   cSubtraction(cExpression *left, cExpression *right) : Left(NULL), Right(NULL)

   {

      Left = left;

      Right = right;

   }

   cSubtraction(<span class="codekeyword">int</span> left, <span class="codekeyword">int</span> right) : Left(NULL), Right(NULL)

   {

      Left = <span class="codekeyword">new</span> cConstant(left);

      Right = <span class="codekeyword">new</span> cConstant(right);

   }

   ~cSubtraction()

   {

      <span class="codekeyword">if</span> (Left) <span class="codekeyword">delete</span> Left;

      <span class="codekeyword">if</span> (Right) <span class="codekeyword">delete</span> Right;

   } 

   <span class="codekeyword">int</span> Evaluate()

   {

      <span class="codekeyword">int</span> Result = 0;

      <span class="codekeyword">if</span> (Left) Result = Left->Evaluate();

      <span class="codekeyword">if</span> (Right) Result -= Right->Evaluate();

      <span class="codekeyword">return</span> Result;

   } 

<span class="codekeyword">private</span>: 

   cExpression * Left,* Right;

};


That sets up our basic arithmetic operators. I actually went in and did hand division just to ensure that I have rounding up and it is proper integer division. Now lets see how we can use
this.



int func()

{

   cExpression *exp1,*exp2,*exp3;

   exp1 = new cAddition(5,7);

   exp2 = new cMultiplication(3,9);

   exp3 = new cSubtraction(exp2,exp1);

   printf("%d", exp3->Evaluate());

   delete exp3;

};


Since I think we can get a much simpler solution out of the code so if I just add a couple more functions to cAddition for an example, you can do the copy paste work to get that working in the
other classes.



 cAddition(cExpression *left, <span class="codekeyword">int</span> right) : Left(NULL), Right(NULL)

{

   Left = left;

   Right = <span class="codekeyword">new</span> cConstant(right);

}

cAddition(<span class="codekeyword">int</span> left, cExpression *right) : Left(NULL), Right(NULL)

{

   Left = <span class="codekeyword">new</span> cConstant(left);

   Right = right;

}


These are two additional constructor functions. Now that they are all through our classes we can do creation as easy as the following:



cExpression *exp = <span class="codekeyword">new</span> cAddition(1, <span class="codekeyword">new</span> cDivision(<span class="codekeyword">new</span> cMultiplication(2,5),4));


This is all well and good, but what good is an equation if there is no way of expressing it before evaluating it?



<span class="codekeyword">char</span> *ToString()

{

   <span class="codekeyword">char</span> *tmp = <span class="codekeyword">new char</span>[10];

   itoa(value, tmp, 10);

   <span class="codekeyword">return</span> tmp;

}



char *ToString()

{

   <span class="codekeyword">char</span> *l,*r,*tmp;

   l = Left->ToString();

   r = Right->ToString();

   tmp = <span class="codekeyword">new char</span> [strlen(l)+strlen®+6];

   strcpy(tmp, "(");

   strcat(tmp, l);

   strcat(tmp, " + ");

   strcat(tmp, r);

   strcat(tmp, ")");

   <span class="codekeyword">if</span> (l) <span class="codekeyword">delete</span> [] l;

   <span class="codekeyword">if</span> ® <span class="codekeyword">delete</span> [] r;

   <span class="codekeyword">return</span> tmp;

}


The first block is for the cConstant class, and the second can be modified for all the classes (just by changing the strcat(tmp, " + "); to a more relevant arithmetic
operator. Then we can change our printout to be:



   ...

   <span class="codekeyword">char</span> *str = exp3->ToString();

   printf("%s = %d", str, exp3->Evaluate()); 

   <span class="codekeyword">delete </span>[] str;

   ...


This gives us a functional calculator for evaluating expressions. For a little homework you might want to write a program that can read in expressions. As for the next article I will be reviewing
those parentheses that we need to insert in our expression printout and how they can be avoided entirely by using a reverse polish calculator. Now here is some thinking material from my code:



exp3 = <span class="codekeyword">new</span> cAddition(1, <span class="codekeyword">new</span> cDivision(<span class="codekeyword">new</span> cMultiplication(2,<span class=

"codekeyword">new</span> cSubtraction(20,5)),4));


Which gives the output:



(1 + ((2 * (20 - 5)) / 4)) = 9

1 2 20 5 - * 4 / + = 9


Note: it is supposed to round up from 8.5 to 9.


Cheers, Chris.


Author: Chris Bennett aka Dwarfsoft
Contact: dwarfsoft@hotmail.com
March 25th, 2004
© Copyright Chris Bennett, 2004








Comments

Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.




PARTNERS