Pass Object By Value Or By Reference

28 Sep 2013

In C++, can you pass object by value? No, you cannot. Of course, this is such a basic concept, but you know what? I still made such stupid mistake recently and couldn’t figure out what went wrong immediately.

Let’s look at some example:

#include <iostream>
using namespace std;

struct A 
{
    virtual void f()
    {
        cout << "This is class A" << endl;
    }
};

struct B: A
{
    void f()
    {
        cout << "This is class B" << endl;
    }
};

struct C: A
{
    void f()
    {
        cout << "This is class C" << endl;
    }
};

void g(A func)
{
    func.f();
}

int main(int argc, char** argv)
{
    A a;
    B b;
    C c;

    g(a);
    g(b);
    g(c);

    return 0;
}

What will the output be after executing such a program?

This is class A
This is class A
This is class A

It turns out that the ‘values’ of objects are not copied over to the local variable func in function g. This is because they are class variables instead of primitive data types; the ‘values’ of class variables cannot just be passed and copied over to the memory box of another class variable which is local to a function. Objects are constructed, not assigned by values.

Therefore, C++ is pass-by-reference for object; or pass-by-value for pointers to objects. To fix the problem in the code above, see the following:

// cleaner and prefered
void g(A& func)
{
    func.f();
}

// Or,
void g(A* func)
{
    func->f();
}

int main(int argc, char** argv)
{
    A a;
    B b;
    C c;

    g(&a);
    g(&b);
    g(&c);

    return 0;
}

So far so good, these are just some review of pass-by-reference and pass-by-value concepts. How about Java and Python? Are they pass-by-value or pass-by-reference?

For Java, it passes object references by value. That means the values of references are copied over. And, object variables are just varables (pointers!) that holds references to objects. To have more in depth, read this.

For python, it is a totally different story. It is neither pass-by-value nor pass- by-reference. How so? Well, its behavior is more like ‘pass object reference by value’; but the thing is, the values of the actual parameters are not copied to the formal parameters of a function, because everything in Python is an object! An object has no ‘value’. The value(s) of formal parameters are ‘constructed’ locally, not copied from.

See this post and this thread.