Lapys
Lapys

Reputation: 946

Return reference to local variable - C++

Question

How does one return a reference to local variable in a function?

#include <stdio.h>

class Array {
    public:
        bool stillAlive;

        inline Array() : stillAlive{true} {}
        inline Array(Array& array) : stillAlive{array.stillAlive} {}
        /* Other constructors... */

        inline ~Array() { this -> stillAlive = false; }

        // My attempt at returning a local reference
        // doesn't work because `tmp` gets destructed after the function returns.
        inline Array& clone() {
            Array tmp;
            Array& arrayClone = tmp;
            return arrayClone;
        }
};

int main(void) {
    Array array {};
    Array clone {array.clone()};

    ::printf("array: %s\n", array.stillAlive ? "true" : "false");
    ::printf("clone: %s\n", clone.stillAlive ? "true" : "false");
    ::printf("array.clone(): %s", array.clone().stillAlive ? "true" : "false");

    return 0;
}

I’ve seen the static keyword but I do not want the reference to be to the same variable always.

With pointers I know memory can be allocated on the heap so I’m pretty okay if the same has to be done with value variables (but I don't think that's possible).


EDIT: Attempted a solution that could use self-contained pointers.

Attempt

How about this then? The local variable references a self-contained pointer which outlasts the scope of the function its called.

#include <fcntl.h>
#include <stdio.h>

class Array {
    private:
        Array *cloneValue;

    public:
        bool stillAlive;

        Array() : cloneValue{NULL}, stillAlive{true} {}
        Array(Array& array) : cloneValue{NULL}, stillAlive{array.stillAlive} {}
        /* Other constructors... */

        ~Array() { delete this -> cloneValue; this -> stillAlive = false; }

        Array& clone() {
            delete this -> cloneValue;
            this -> cloneValue = new Array;

            Array& arrayClone = *(this -> cloneValue);
            return arrayClone;
        }
};

int main(void) {
    Array array {};
    Array clone {array.clone()};

    ::printf("array: %s\n", array.stillAlive ? "true" : "false");
    ::printf("clone: %s\n", clone.stillAlive ? "true" : "false");
    ::printf("array.clone(): %s", array.clone().stillAlive ? "true" : "false");

    return 0;
}

It seems to work as intended and there doesn't seem to be any memory leakage either.

Upvotes: 0

Views: 297

Answers (1)

Zan Lynx
Zan Lynx

Reputation: 54353

You can't do it.

Return a copy of the local variable instead.

Because of the magic of C++11 move constructors, this will often be optimized away. I've even seen machine code which removed the move itself and operated as if the function had been passed a pointer to the object receiving the move.

With C++11 and later, it seems best to program as if copies are free. Then profile your code and if there really is a copy problem you can optimize it then.

Upvotes: 3

Related Questions