First Principles of C++: this, this->, *this
When a new class or struct object is created memory is allocated only to its data members, whereas member functions are stored in common code segment like a blue print.
Then how member functions are able to access its own data members. Here comes 'this' keyword.
'this' is simply a pointer that is passed to member functions of a class implicitly, pointing to the memory location where the object resides.
This can be confirmed using small test code,
#include <iostream>
class Laboratory {
public:
/**** Member Variable ****/
int value;
/**** Member Functions ****/
Laboratory(int v): value(v) { }
void print() {
std::cout << "Value in 'this' pointer : " << this << std::endl;
}
void display() {
std::cout << "Member accessed using 'this' : " << this->value << std::endl;
}
};
int main() {
Laboratory test(10);
std::cout << "address of 'test' object : " << &test << std::endl;
test.print();
std::cout << "size 'test' object : " << sizeof(test) << std::endl;
int *ptr = (int *)&test;
std::cout << "dereferencing 'test' object : " << *ptr << std::endl;
return 0;
}
/*** Output: ***/
address of 'test' object : 0x7ffd4d19c054
Value in 'this' pointer : 0x7ffd4d19c054
size 'test' object : 4
dereferencing 'test' object : 10
Firstly, size of the class object is the size of total variable. Here, size of 'test' object is 4 which is size of member variable 'value'
Secondly, So address of test object &test and value of 'this' are same which is the address of first non-static variable 'value'. This can be confirmed by dereferencing &test to a integer.
'this' is a address which is a rvalue. Like a typical pointer, to access the value of data member you can use this->member variable.
In a software design need like Method chaining, Operator chaining, Operator overloading where class object is returned from the class member function. Returning class object by reference is highly recommended than returning by value or pointer. This is achieved by dereferencing *this.
class MyClass {
private:
int value;
public:
MyClass& setValue(int newValue) {
this->value = newValue;
return *this;
}
MyClass& incrementValue(int increment) {
this->value += increment;
return *this;
}
void printValue() const {
std::cout << "Value: " << value << std::endl;
}
};
int main() {
MyClass obj;
obj.setValue(10).incrementValue(5).printValue(); // Method chaining
return 0;
}
Here, in example all the methods are returning its own object. In main() all the methods can be called in a single line obj.setValue(10).incrementValue(5).printValue();
领英推荐
obj.setValue(10) returns *this which is 'obj' [ this is holding the address of the object, so dereferring this will be referring to object], so using the return obj incrementValue(5) is called. Which again return 'obj' and called printValue() method is called. This is called Method chaining.
Here Method chaining like this obj.setValue(10).incrementValue(5).printValue(); can be achieved only using returning the object by reference. In case of returning object by pointer same achieved using -> operator like obj.setValue(10)->incrementValue(5)->printValue();
You would have use Method chaining unconsciously many time like this,
std::cout << "Hello" << "World" <<"Vijay";
This is called operator chaining.
First Principle of C++ series of article is for deeper though people who wish to explore under the hood and from compiler perspective.