In C++, member functions get executed in the context of an object. And a special pointer, this, holds the address of that object. We can return the address (pointer), reference or a copy of that object using the this pointer from a member function of a class.
Returning the Object Pointer
#include <iostream>
using namespace std;
class c1 {
public:
int var_;
c1 *getPoiter() {
return this;
}
};
int main() {
c1 obj;
c1 *p = obj.getPoiter();
obj.var_ = 100;
/*Access the member variable using the pointer*/
cout << "The member variable value: " << p->var_ << endl;
cout << endl << "Address of the object: " << &obj << endl;
cout << "Value of the pointer variable: " << p << endl;
cout << endl << "Adress of the pointer variable: " << &p << endl;
return 0;
}
$ g++ -o test test.cpp
$ ./test
The member variable value: 100
Address of the object: 0x7fffe2ed876c
Value of the pointer variable: 0x7fffe2ed876c
Adress of the pointer variable: 0x7fffe2ed8770
Here the getPointer() function of class, c1, simply returns the this pointer. The returned value will be the address of the calling object.
In main(), the pointer variable, p, holds the return of the getPointer() function. Using this pointer, we can now access the members of the object, obj. We set the member variable of obj to 100. We printed that variable via the pointer, p.
The next two prints confirmed that the variable, p, really points the object, obj. The means that the value of p is equal to the address of obj.
However, p is a different variable and its memory address is also different. The next print confirmed that.
Returning a Copy of the Object
#include <iostream>
using namespace std;
class c1 {
public:
int var_;
c1 getObject() {
return *this;
}
};
int main() {
c1 obj;
obj.var_ = 100;
c1 obj1 = obj.getObject();
cout << "Member variable of obj: " << obj.var_ << endl;
cout << "Member variable of obj1: " << obj1.var_ << endl;
obj.var_ = 200;
cout << endl;
cout << "Member variable of obj: " << obj.var_ << endl;
cout << "Member variable of obj1: " << obj1.var_ << endl;
return 0;
}
$ ./test
Member variable of obj: 100
Member variable of obj1: 100
Member variable of obj: 200
Member variable of obj1: 100
If the ‘this’ pointer points to the calling object, then ‘*this‘ will be the actual object. So, to return the object, we need to return ‘*this‘ instead of ‘this‘.
In this example, the getObject() function returns a copy of the calling object. In main(), we first set the member variable of obj to 100 and then assigned the returned value of getObject() to obj1.
As obj1 is a separate copy of obj, both the objects will have same values for the member variables right after the copy. We can that in first two print statements.
Changing one object will not impact the other object. We changed the member variable of obj to 200. But obj1 maintained the old value of the member variable 100. The next two print statements showed that.
Returning the Object Reference
#include <iostream>
using namespace std;
class c1 {
public:
int var_;
c1 &getReference() {
return *this;
}
};
int main() {
c1 obj;
obj.var_ = 100;
c1 &obj1 = obj.getReference();
cout << "Member variable of obj: " << obj.var_ << endl;
cout << "Member variable of obj1: " << obj1.var_ << endl;
obj.var_ = 200;
cout << endl;
cout << "Member variable of obj: " << obj.var_ << endl;
cout << "Member variable of obj1: " << obj1.var_ << endl;
return 0;
}
$ ./test
Member variable of obj: 100
Member variable of obj1: 100
Member variable of obj: 200
Member variable of obj1: 200
Returning the object reference is very similar to returning a copy of the object. Only we need to put an ‘&‘ before the function. In this example, the getReference() function returns a reference of the calling object.
We assigned the returned object reference to obj1. Here, obj1 is a reference of the object, obj. It means that both obj and obj1 refer to the same object. In other words, obj1 is yet another name of obj. If we change the object using one variable, we can see the impact using the other one.
In this example, we changed the member variable to 200 using obj and printed that value using both obj and obj1. We can see that both values are same.
Returning an object reference from a member function allows us to implement method chaining.
One important thing to note here is that we have assign the returned value to a reference type variable like this.
c1 &obj1 = obj.getReference();
But if call like this:
c1 obj1 = obj.getReference();
The obj1 will be a separate copy of obj. They will be two different objects – not the reference of one another.