0

I currently have to write a program that allows a user to pick between two objects to test. This isn't the same program exactly but it's the same premise.

class defined by header file

#include <iostream>

class example {
private:
    int x;
public:
    example() {
        x = 10;
    }
    void setNum(int input) {
        x = input;
    }
    int getNum() {
        return x;
    }
};

Test main and selectObj method

#include <iostream>
#include "Header.h"



example selectObj(example A, example B) {
    int selection;
    std::cout << "Select object 1 or 2: ";
    while (true) {
        std::cin >> selection;
        if (selection == 1)
            return A;
        else if (selection == 2)
            return B;
        else
            std::cout << "Inavlid option, try again: ";
    }
}



int main() {
    example test1, test2;
    selectObj(test1, test2).setNum(25);
    std::cout << selectObj(test1, test2).getNum();

    return 0;
}

selectObj is supposed to return an object. It runs but it isn't doing what setNum is supposed to do.

Suppose you choose option 1 for both calls of selectObj. It looks something like this.

Select object 1 or 2: 1
Select object 1 or 2: 1
10

It should have printed out 25 but instead, setNum isn't really changing the value of test1.

However, if I write

test1.setNum(25);
std::cout << test1.getNum();

Then it does indeed set test1's x value to 25.

Again, this isn't exactly like the program I had written (it is changed now and wouldn't like to rewrite that). However, it is an identical representation of the same concept.

Cascades
  • 627
  • 7
  • 18
Sxivy
  • 1
  • Your `selectObject` function returns a copy (and also takes copies as arguments) - calling `setNum` on the returned value doesn't modify the objects defined in `main` in any way – UnholySheep Nov 01 '21 at 23:39
  • Does this answer your question? [Pass by Reference / Value in C++](https://stackoverflow.com/questions/410593/pass-by-reference-value-in-c) – Stephen Newell Nov 01 '21 at 23:40
  • To work as you expect, `selectObj()` needs to return a reference and, since it is trying to return a reference to objects supplied as arguments, its arguments also need to be passed by reference. Instead, `selectObj()` is passed both arguments by value (so the objects passed by the caller are copied) and it returns by value (so returns a copy of the object selected). – Peter Nov 01 '21 at 23:55

1 Answers1

3

You are calling setNum on the temporary object created by the return statement in selectObj. That object stops existing as soon as setNum returns, so the change is lost.

Imagine if you did this:

int selectInt (int a, int b)
{
    if (a > b) return a;
    return b;
}

int a = 3;
int b = 4;
selectInt(a, b)++;

This wouldn't modify either a or b, because what was passed to selectInt was two values, 3 and 4. And what was returned was a value. There is no way this code could modify a or b. In fact, you could do this:

selectInt(1, 2)++;

And clearly there is no persistent object that could be modified. If you want to pass objects by reference, you need to do that -- both to and from your function.

Did you mean this?

example& selectObj(example& A, example& B) {
    int selection;
    std::cout << "Select object 1 or 2: ";
    while (true) {
        std::cin >> selection;
        if (selection == 1)
            return A;
        else if (selection == 2)
            return B;
        else
            std::cout << "Inavlid option, try again: ";
    }
}
David Schwartz
  • 179,497
  • 17
  • 214
  • 278