Nick
Nick

Reputation: 10539

how function/method returns reference to object works internally

This is probably a duplicate, but suppose we have following code

#include <stdio.h>
#include <stdlib.h>

class IPair{
public:
    IPair(const char *s) : s(s){
        buffer = malloc(1024);
    };

    virtual ~IPair(){
        free(buffer);
    }

    virtual void print() const = 0;

    const char *s;
    void *buffer;
};

class Pair : virtual public IPair{
public:
    Pair(const char *s) : IPair(s){};

    virtual void print() const override{
        printf("Hello %s\n", s);
    }
};

Pair createPair(const char *s){
    return Pair(s);
}

IPair & usePair(IPair &pair){
    pair.print();

    return pair;
}

int main(int argc, char** argv)
{
    Pair a = createPair("AAA");
    Pair b = createPair("BBB");

    usePair(a);
    IPair &x = usePair(b);
    usePair(x);

    return 0;
}

If examining with valgrind, there is no memory leak - e.g. destructor is called on correct "place".

This raise following questions:

  1. what exactly happens inside createPair()? Looks like object memory is copied. Is it memcpy()-like or have something to do with copy constructor?
  2. usePair() get reference, then return same reference back. since the referred object is still in main() scope, this should be safe operation - is this assumption correct?

Upvotes: 0

Views: 81

Answers (2)

marom
marom

Reputation: 5230

  1. In create Pair an object is constructed and then returned. This involves a copy constructor (avoidable if Pair implements a Move constructor). IN addition RVO (return value optimization) may help avoid unnecesary copying)
  2. usePair deals with references and no copying happens here. It's perfectly OK.

P.S. Declare destructor of IPair virtual...

Upvotes: 3

Mats Petersson
Mats Petersson

Reputation: 129344

  1. Like Copy Constructor - if no constructor is provided, the compiler will make one, which is essentially memcpy(*this, rhs, sizeof(*this));. Return value optimisation, which is that the compiler passes in the address of the destination to store the value in - removing the need for a copy in most cases. [Actually, all structure/class returnes will modify the call such that the compiler passes the object to be returned as a reference parameter]

  2. References are nearly the same as pointers in C++, so when you return a reference, the address of the object is returned. The difference is that references don't need a dereference operator, and can only ever be assigned once.

Upvotes: 3

Related Questions