2

I am trying to determine whether the variable a user instantiates is present within an equation. I have the class declared as follows:

#ifndef EQUATION_H
#define EQUATION_H
#include "Expression.h"
#include "Shunt.h"
#include <string>
#include <map>

using namespace std;

class Equation
{
   public:
      Equation(string eq);//If an equation is invalid, throw an exception string
      Equation(const Equation& other);
      Equation& operator=(const Equation& other);
      ~Equation();
      int evaluateRHS();//If at least one variable does not have a value, throw an exception string
      int evaluateLHS();//If at least one variable does not have a value, throw an exception string
      void instantiateVariable(char name, int value);//If does not exist in the equation, throw an exception string
      int RHSdistanceFromLHS();//If at least one variable does not have a value, throw an exception string
      string original;
      map<char, int> variables;
   private:
      Expression* left;//Left side of the equals
      Expression* right;//Right side of the equals
};
#endif

and implement instantiateVariable in the following:

void Equation::instantiateVariable(char name, int value)
{

  short firstLen = left->equationPart.length();
  short secLen = right->equationPart.length();

  bool exists = false;

  for(short i = 0; i < firstLen; i++)
  {
     if(left->equationPart[i] != name)
     {
        exists = false;
     }
     else
     {
       exists = true;   
     }
  }

  if(exists == false)
  {
    for(short i = 0; i < secLen; i++)
    {
       if(right->equationPart[i] != name)
       {
          exists = false;
       }
       else
       {
          exists = true;      
       }
    }    
  }  

    if(exists == false)
    {
        string er = "error";  //Not caught successfully. Terminates entire program.
        throw er;
    }


    variables[name] = value;

}

When called in the main function:

void testCase3()
{
        try
    {          
        Equation equation3("(y - (x + 3) ^ y) * 5 / 2 = log 20 - y");
        equation3.instantiateVariable('z',3);   
    }
    catch(string ex)
    {
        cout<<"Exception thrown"<<endl;
    }
}



int main(int argc, char** argv)
{
   testCase3();

}

the following error occurs:

terminate called after throwing an instance of 'std::string'
Aborted
Zenadia Groenewald
  • 107
  • 1
  • 3
  • 12
  • There is a bug in your `instantiateVariable` for loops in the if `equationPart[i] != name` conditional: if name exists for say `i==1` then `exists` is set to `true`; if name does not exist in `i==2` then `exists` is reset to false. You should just have `if(equationPart[i] == name) { exists = true }` -- your initialization of `exists` to false takes care of the non-exists case. – reece Oct 13 '12 at 12:06
  • Thanks. Didn't see that. – Zenadia Groenewald Oct 13 '12 at 12:09
  • 2
    aside, have you considered using std-exception classes, like http://www.cplusplus.com/reference/std/stdexcept/runtime_error/ ? it helps having all exceptions in the `exception` class hierarchy – Rudolf Mühlbauer Oct 13 '12 at 12:10
  • further aside, there is seldom a good reason to make the (Equation-) destructor non-virtual, http://stackoverflow.com/a/461224/1689451 – Rudolf Mühlbauer Oct 13 '12 at 12:13
  • 1
    which one? we should create an answer to solve this question. – Rudolf Mühlbauer Oct 13 '12 at 12:16
  • You need to catch reference not copy. So catch std::string& not just std::string. – Zaffy Oct 15 '12 at 05:42

1 Answers1

1

Please try to catch a const reference,

 catch(const string& ex) {}

see https://stackoverflow.com/a/2522311/1689451

Community
  • 1
  • 1
Rudolf Mühlbauer
  • 2,511
  • 16
  • 18
  • That works, but it has to catch a string specifically. Probably should've mentioned that beforehand. – Zenadia Groenewald Oct 13 '12 at 11:56
  • All other exceptions thrown in other member functions work just fine, it's just this specific exception that doesn't seem to work. – Zenadia Groenewald Oct 13 '12 at 11:58
  • In my minimal working example, it just works fine -- i cannot see any problem with your code. Interesting! – Rudolf Mühlbauer Oct 13 '12 at 12:01
  • Indeed. In the other member functions, the exceptions are thrown in exactly the same way; I cannot understand why it won't work for this one case... – Zenadia Groenewald Oct 13 '12 at 12:09
  • @ZenadiaGroenewald: If you want a real answer then you need to reduce the code to the minimal **compilable** example that reproduces the problem (so we can run it). If you throw a std::string and then catch it (by value or reference) the code will work in all normal modern compilers. So either there is something you are not showing us (very likely) or your compiler is buggy (very very unlikely) or you have a very old compiler (unlikely). – Martin York Oct 13 '12 at 13:25
  • @RudolfMühlbauer: This does not answer the question. Comments on best practice are best introduced as comments. This does not solve the stated problem above. – Martin York Oct 13 '12 at 13:26
  • @LokiAstari, you are right - i will behave in future ;) I thought it might just be the answer. – Rudolf Mühlbauer Oct 13 '12 at 13:27