I’m working on a simple function (or set of functions) that will add, substract, multiply and divide. This is what I came up with (the counter part is important to my program but irrelevant to my question. Suffice to say that all 4 operations would store the result in those same variables and that only the operator would be changed):
void Chiffres::add(int num1, int num2)
{
int add1;
int add2;
cout<<"enter first number to be added:"<<endl;
cin>>add1;
cout<<"enter second number to be added:"<<endl;
cin>>add2;
counter++;
if (counter == 1)
e = add1+add2;
else if (counter == 2)
h = add1+add2;
else if (counter == 3)
j = add1+add2;
}
Now, I can copy this four times, edit the user prompt as needed and replace the (+) signs within the if/else statements with the appropriate operator to create 4 separate functions and it’ll work fine. However, it seems ugly and wasteful. I could also combine them all in one function and use a switch statement inside to select the appropriate user prompt and the operation to be performed. However, it’ll still be ugly and unefficient. So, how would you guys go about it?
You could create a hierarchy of functors* that perform specific operations, and pass these as an argument to a generic operation function. Although you’d still need to work out the correct prompt. And it would still be ugly. And wasteful.
*A functor in the C++ context is an object that behaves like a function (other languages use “functor” to mean other things, there’s three different definitions from three different languages that I know of, probably more. You need to overload operator (), like so:
class FunctorBase {
public:
virtual int operator () (int one, int two) const = 0;
};
class AddFunctor : public FunctorBase {
public:
virtual int operator () (int one, int two) const;
};
... implementation ...
int AddFunctor :: operator () (int one, int two) const
{
return one + two;
}
Although I see nothing particularly wrong with the switch approach, to be honest.
A functor is an object that acts like a function. Meaning that you can “call” it like a function. Which in C++ terms is an overload of the () (function call) operator.
virtual int operator()(int one, int two) … is a declaration for the overload. It indicates that when you “call” this object, you’ll be passing two integer params. For example:
AddFunctor a; // Create one
a(50, 20); // Call it with 50, 20
The “const” on the end of the definition is just good style; it’s letting the compiler know that this function doesn’t modify the state of the object (i.e. it doesn’t change any member variables. Since these classes don’t have any, all their methods can safely be declared const.) You could leave this off to no real effect other than getting purists to yell at you.
The “= 0” on the base class defintion indicates that the function is “pure virtual”, or equivalently that the base class is “abstract.” A pure virtual function means that any non-abstract subclass of the class must override that function. Here, it’s just saying that anything derived from FunctorBase must have an override of the operator() function. This allows polymorphism (you can assume everything has an operator() function, and therefore treat all Fuinctors as FunctorBases in most cases), without having to (necessarily) provide a default implementation. The compiler will throw an error if anyone derives a class from FunctorBase but doesn’t override that function.
C++ has no verb or function equivalent to the Interpret function of Rexx?
You are making them enter all the terms of the math you want, anyway. In Rexx, you would simply set up your input to include all the variables and all the operators and execute
No. C++ is really the wrong language for parsing expressions anyway. Besides, why have a function for parsing mathematical expressions and not one for, say, parsing Pascal or Lisp expressions?
No, you’ll only find that in languages that are either VM-based (“managed” in Microsoft’s parlance) or interpreted. In C++, the compiler isn’t around after compilation, in particular it’s not around at runtime. It’s part of the cost paid for speed and low level access.
The system() trick could work on a system that supports it (most don’t), and Microsoft has something called CodeDOM as part of .NET that gives you the ability to “interpret” text in a .NET language, but these are platform-specific solutions, not in the standard C++ API. (And if you think Functors are exotic, I dare you to make heads or tails of CodeDOM).