2

How can we return a variable by reference while the scope of the returning function has gone and its vars have been destroyed as soon as returning the var?

And if we make as the following to avoid that:

int fr = 9;
int& foo() {
    //const int& k = 5;
    return fr;
};

I will ask must we declare the returned var as a global var?

DeiDei
  • 10,205
  • 6
  • 55
  • 80
asmmo
  • 6,922
  • 1
  • 11
  • 25

5 Answers5

3

You can return a function local static variable instead of a global variable, of course:

int& foo() {
    static int rc = 9;
    return rc;
}

Note, however, that you still effectively have a global variable with all its problems, e.g., potentially concurrent access from multiple threads. At least, starting with C++11 the initialization of function local static variable is thread-safe: a function local static variable is initialized upon the first execution of the declaration statement.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
3

Use the static keyword so that its scope remains throughout the code. Example:-

  int& fun(){
  static int a =5;
  return a;
  }

 int main()
 {
  int &b=fun();
  cout<<b;
 }
Naveen
  • 56
  • 3
2

You can create a class and introduce a member, which you return as reference. This would be more transparent, than the 'static function member' solution, but requires more overhead, so that it is only reasonable, if you need a class anyway.

class Foo {
public:
   Foo() ;
   int& getFoo() {return myFoo;} 
private:
   int myFoo;
};
tangoal
  • 724
  • 1
  • 9
  • 28
  • Not sure what do you mean by "*requires more overhead*" -- this is fundamentally the same as OP's global variable approach (or the `static` approach). In other words, the function is returning a reference to a pre-existing object allocated somewhere (the scope of the referenced variable is not gone due to the function ending). – Acorn May 20 '18 at 19:28
  • @Acorn: I don't know the overall target of the thread opener. Designing classes can be overhead for a very short program, that's what I mean. – tangoal May 20 '18 at 19:35
  • Designing a class here does not buy us anything -- the problem is moved somewhere else (i.e. where the class was allocated). Don't get me wrong: returning references to members is actually very common and nothing to be surprised of, but the scope of the original variable is not gone (which I feel the question was about). – Acorn May 20 '18 at 19:44
1

Note: OP and the other answers suggest variations on returning a pre-existing object (global, static in function, member variable). This answer, however, discusses returning a variable whose lifetime starts in the function, which I thought was the spirit of the question, i.e.:

how can we return a variable by reference while the scope of the returning function has gone and its vars have been destroyed as soon as returning the var.

The only way to return by reference a new object is by dynamically allocating it:

int& foo() {
    return *(new int);
}

Then, later on:

delete &myref;

Now, of course, that is not the usual way of doing things, nor what people expect when they see a function that returns a reference. See all the caveats at Deleting a reference.

It could make some sense, though, if the object is one of those that "commits suicide" later by calling delete this. Again, this is not typical C++ either. More information about that at Is delete this allowed?.

Instead, when you want to return an object that is constructed inside a function, what you usually do is either:

  • Return by value (possibly taking advantage of copy elision).
  • Return a dynamically allocated object (either returning a raw pointer to it or a class wrapping it, e.g. a smart pointer).

But neither of these two approaches return the actual object by reference.

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • 1
    this is very interesting.Thanks a lot – asmmo May 20 '18 at 11:58
  • Interesting approach, but with pitfalls. Each time you call the function, you get a new allocation. User must delete that by himself. However, good that you pointed out that by yourself. – tangoal May 20 '18 at 18:08
  • @tangoal: What do you mean? The question is about returning a reference to a variable from a function whose scope is gone. The other 3 answers are variations about returning a pre-existing object (different scope than the function's -- debatable if they answer OP's specific question). The only other alternative is this one (returning a new object) -- and you have to do it through a dynamic memory area, since OP asked to return a reference. – Acorn May 20 '18 at 19:54
  • @Acorn: Look, I didn't downvote your answer. As said it is interesting and it matches to the original question. I just wanted to point out that your proposal promotes memory leaks, since the user of the function foo() needs to know that it needs to delete the memory again. That is not obvious, because it returns a reference and not a pointer. However, thanks for your post, I was not aware of that option. – tangoal May 20 '18 at 22:37
  • @tangoal: No worries! The answer is not trying to provide how to properly design interfaces; rather, just answering the question as given (and then warning the reader just in case :-) The downvote is probably coming from someone that firmly believes StackOverflow should be about "a manual of good/popular practices", rather than facts. – Acorn May 20 '18 at 22:42
0

I'm assuming it's an academic example to examine a principle because the obvious way to code it would otherwise be to return by value.

With this precondition in mind this looks like a use case for smart pointers. You would wrap the variable in a smart pointer and return by value. This is similar to @Acorns answer but the variable will self delete once it is no longer being referred to, so no need for an explicit delete.

Rich
  • 4,572
  • 3
  • 25
  • 31