Confused about returning by reference.

How can I safely return a reference to an object?
Last edited on
Is this the only rule to follow when returning
by reference? To be sure that the value returned
does not go out of scope?
The reference will become invalid if the lifetime of the object you are referencing ends, so that is what you need to avoid.

Your first case is valid because a is a global variable and will be initialized before main starts, and destroyed after main ends.

Your second case doesn't compile, but if we modify to compile...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class test {
  public:
    static int a;

    static int& getRef() {
        return a;
    }

    static int getA() {
        return a;
    }
};

int test::a = 10;


Then it will also be valid, because static class variables exist for the lifetime of the program.

Note: If by "safe" you are talking about thread safety instead, then you should have locks/mutexes to ensure only one thread is ever writing the static or global variable at a time.

Edit: You removed your code example. Why?
Last edited on
Okay, thanks for clearing that up.
Though I do not know what locks/mutexes are.
I do not know if I meant thread safety. If I do
understand what that is should I just not return
by reference?
Okay, forget about thread safety for now, since it will just confuse you more.
Let's just assume we're dealing with one thread.

The solution is not to avoid using references. They are useful constructs to use. The solution is to understand it, so it's good that you're asking questions.

This is bad:
1
2
3
4
5
int& foo()
{
    int obj = 42;
    return obj;
}

This is bad because obj is a local variable, and will be destroyed after this function exists.

This is good:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

class Foo {
  public:
    int& bar()
    {
        return obj;
    }
  private:
    int obj = 42;
};

int main()
{
    Foo foo;
    foo.bar() = 43;
    std::cout << foo.bar() << '\n';
}

because foo -- and therefore foo::obj -- exists for longer than the function itself; it exists for the entire scope of main.
Last edited on
Okay. So, what I understand from this is that an object and its reference must exist
for the same amount of time, or the referenced object must exist longer? I'm sorry,
I may still be a bit confused.
Last edited on
the object referred to must exist at the time the reference is used.
a function destroys the local, non static variables when it exits, so references to them are no longer valid if you try to use them.
wrapping them in a class or making them static or passing them into the function all provide ways around the issue. Global variables also are a way around it, but that is a poor choice.

1
2
3
4
5
6
7
8
9
10
11
12
13
int& foo()
{
    static int obj = 42;  //ok: static makes obj last until program ends, not function end. 
    return obj;
}


int& foo(int &obj)
{
    obj = 42;
    return obj;  //ok, it was passed into the function, so it exists somewhere else. 
}


and the above class idea can be done as a functor ( a class that acts like a function by overloading () operator) as well.

for an integer, copying it is just as efficient, possibly moreso, than returning a reference anyway.
Last edited on
Okay. Thanks a lot! :D
Topic archived. No new replies allowed.