The pointer this

The memory layout of class objects

The memory layout of class objects is the same as the layout of structure objects. The members are stored, in memory, in the same order they are defined, and they may be padded. Also, like structure objects, the size of a class object is of at least 1 byte, even if it has no member variable.

Even though classes possess functions (Called methods), they are obviously not stored inside the objects. A method is a function, the only real difference is that it has access to the members of the object that calls it. When a method is called, the members of the object that called it can be seen as references (Constant if the method is constant) that are automatically given in argument to the 'function'.

The problem

Let us say we are defining a method and we want to retrieve the address of the object the method is called from. How do we achieve that? A way would be to retrieve the address of the first member variable of the class and consider it to be the address of the object as the first member variable is stored, in memory, at the start of the object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream> class A { public: A() : _a(123.123){} void printA() const { std::cout << _a << std::endl; } void method() const { /* Retrieves the address of the member '_a' and explicitly casts it to a pointer of type 'const A'. */ const A *ptr = (const A*)&_a; // To prove it really points to the object. ptr->printA(); } private: double _a; }; int main() { A a; a.method(); return 0; }

It works, but it is not very elegant nor practical and it prevents the first member variable to potentially be optimized out by the compiler. Also, what if the class possesses no members?

The solution

There is a special pointer, defined in each method of each class, named this, which points to the object the method is called from. We can therefore use it, instead of the trick shown above, to retrieve a pointer (address) to the object the method is called from.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream> class A { public: A() : _a(123.123){} void printA() const { std::cout << _a << std::endl; } void method() const { // Both lines are equivalent. printA(); this->printA(); } A * address() { // Returns the address of the object. return this; } private: double _a; }; int main() { A a; a.method(); // Shows the pointer 'this' is equivalent to the address of the object. std::cout << &a << std::endl; std::cout << a.address() << std::endl; return 0; }