0

I have two functions that do the same thing: they add two numbers. One adds two numbers which are members of the class, the other adds numbers given by the user, outside the class.

Is there any way to write one single function that adds two numbers and checks whether the arguments are user input or class members?

void myclass::add(){
cout<<this->a+this->b;
}

void myclass::add(int a,int b){
cout<<a+b;
}
3
  • It would be great if you could state the purpose or what you would like to achieve with it. It might make it easier for us to help you out. Just a small hint for now: If you want to check the origin of a variable, you might use its location. To use the location of arguments a, b, they need to be provided as reference or pointer. Commented Feb 2, 2015 at 16:00
  • 2
    I don't see the utility in what you're trying to do. What is the problem you're really trying to solve? Commented Feb 2, 2015 at 16:02
  • I tried to simplify it a bit to avoid explaining my whole project. Commented Feb 2, 2015 at 16:07

4 Answers 4

6

While you cannot really do it in a single function the common approach would be to write the more flexible of the two and use the other one just as a dispatcher:

void myclass::add(int a, int b) {
   std::cout << (a+b);
}
void myclass::add() {
   add(a,b);
}

Now, there are a different number of smells in this code... a function name reused to act on members or only inputs is one (a function that does not touch the object's state already smells at it not being a member, or being a static one). Printing inside a function called add (should it not return the values?)...

Sign up to request clarification or add additional context in comments.

1 Comment

Sure you can do it in one function
0

Disclaimer : I don't encourage such coding.

Ok, here's a method

 void myClass::Add(int& a, int& b)
 {
    if (&a==&this->a)
    {
        std::cout << this->a + this->b
    } else {
        std::cout << a+b;
    }
 }

Ofc , things like myClass->Add(10,4) won't work... you will need some stack variables to hold the 10 and 4 variables.

Comments

0

So you want a single function that can have two different parameters? It isn't possible.

void myclass::add(int a, int b)
{
    cout << a + b << endl;
}

Is what you want; but you can overload the function:

void myclass::add()
{
    cout << memberA + memberB << endl;
}

In my opinion, this is a much better solution than having a single function that checks whether the variables are members or not; it makes your code readable. Don't be afraid to overload functions - it's one of those things that makes C++ awesome. I've created a class to demonstrate this:

class myClass
{
public:

    myClass() : memberA(0), memberB(0) {}
    ~myClass() {}

    void setNumbers(int a, int b)
    {
        memberA = a;
        memberB = b;
    }

    void add(int a, int b)
    {
        cout << a + b << endl;
    }

    void add()
    {
        cout << memberA + memberB << endl;
    }

private:
    int memberA;
    int memberB;
};

int main()
{
    myClass m;

    m.setNumbers(1, 2);
    m.add();

    return 0;
}

I've tested the add function with and without parameters and they both output the same result. The former because I used a setNumbers(..) function. Effectively, your first scenario of having two functions is the most apt solution to begin with.

1 Comment

Well if the functions are big I have to copy/paste their whole bodies. This works in this small case of addition, but if they do much more it becomes troublesome.
0

In you realy wanted a single function, the way to do it is with optional default parameters.

Your declaration will be

void add(optional<int> a = optional<int>(), optional<int> b = optional<int>() );

Then in your implementation:

a ? a.get() : this->a

A benefit of this approach is that you can mix members and parameters. For example:

obj.add(1);
obj.add(optional<int>(), 2);

9 Comments

That could be a benefit or a curse, the original design had one of two operations: two members or two arguments, this approach breaks that allowing mixed operations that might or not make sense. Can it be done? of course as you mention it can be done, everything can be done, for example, you could tag which flavor you want: void add(tag t, optional<int> a = ... , optional<int> b = ...) and internally based on t either require that both or none of the optional arguments are set, but that changes the syntax for the caller
@DavidRodríguez-dribeas: Why is it a curse? The concern you mention here can easily be avoided by requiring both or none of the parameters to be set thus avoiding the side effect I mentioned. On another note, the question is "Can I?" not "Should I?". My response answers the question "Can I" with yes and provides one example how to do it. Your answer incorrectly states that one "cannot really do it" and instead answers another, more subjective question - "should I" - by applying the DRY principle to the original 2 functions.
The interface that you provide has a completely different contract than the original one. You can default none, one or both arguments, this changes the semantics of the type, and that is why I believe that your solution does not solve the original problem, but builds on a different design. The original design can be attained by adding additional burdens to the caller (specify which flavor they want) or runtime (testing for nullity of the arguments). Both of them can impact your code in different ways (the compiler won't catch a call with one argument, the cpu might stall if it mispredicts...)
Can you reshape the requirements into something for which you can provide a less efficient single function solutions? Yes, of course, but this is neither the solution to the original problem, nor a better design than writing two overloads.
@DavidRodríguez-dribeas: i disagree that the contract is "completely" different. Every caller of the original 2 function approach will work with this function. And of course it is a different design, it has to be different - the question asked for it. Read the question again. Your response wrongfully answers it with no. The question did not ask for an efficient or proper design. It asks whether 1 single function can be written and checks whether there are arguments. This solution solves the problem as per requirements. Your solution changes the requirements as to do a proper design.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.