The ‘this’ Pointer Usage in C++

We discussed about the concept of this pointer in this article. The C++ compiler internally manages it. In general, we don’t need to worry about it. But there are scenarios where we need to use it explicitly.

Resolving Ambiguity between Member and Input Variables

A member function of a class deals with two types of variables – member variables and input variables. But ambiguity arises when a member variable and an input variable have the same name. The ‘this‘ pointer is the rescue in this situation. We can access the member variable using ‘this‘ and input variable with its name.

#include <iostream>
using namespace std;

class c1 {
public:
    int x;

    void setX(int x) {
        this->x = x;
    }
};

int main() {
    c1 obj;

    obj.setX(10);

    cout << "Member x: " << obj.x << endl;
    
    return 0;
}
$ g++ -o test test.cpp 
$ ./test 
Member x: 10

The setX() function of the class c1 sets the member variable, x, with the input argument. But as the both names are same, the member variable is accessed via the this pointer. Variable name without this pointer will refer to the input variable in this situation.

Object Destroying Itself

We can delete the object from a member function that called the function – kind of suicide. We can do that by deleting the this pointer. We need to be careful here. The delete statement should be the last operation performed on the object. After that, the object gets invalidated. And accessing the object can lead to undefined behavior or even program crash.

#include <iostream>
using namespace std;

class c1 {
public:
    int mem_;

    void endMe() {
        delete this;
    }
};

int main() {
    c1 *obj = new c1();

    obj->endMe();

    // The following statement can lead to undefined behabior or program crash.
    // cout << obj->mem_ << endl;
    
    return 0;
}

In this example, we deleted the object itself from endMe() function. After that we should not try to access the object.

Returning the Object Itself

From a member function, we can return the reference of the object the function was called from. It can help us to implement chain function calls like the example below.

#include <iostream>
using namespace std;

class c1 {
public:
    int x;
    int y;

    c1 &setX(int v) {
        x = v;
        return *this;
    }

    c1 &setY(int v) {
        y = v;
        return *this;
    }

    void print() {
        cout << "x = " << x << ", y = " << y << endl;
    }
};

int main() {
    c1 obj;

    obj.setX(1).setY(2);
    obj.print();

    return 0;
}
$ ./test 
x = 1, y = 2

Managing Backpointer

Managing backpointers becomes easy with the this pointer. Backpointer is a colloquial term used by the programmers to refer a pointer held by an object to its parent.

#include <iostream>
#include <string>
using namespace std;

class node {
public:
    node(string name, node* parent = NULL) {
        name_ = name;

        child_ = NULL;
        parent_ = parent;
    }

    string &name() {
        return name_;
    }

    node *parent() {
        return parent_;
    }

    node *addChild() {
        child_ = new node("child", this);

        return child_;
    }

private:
    string name_;

    node* child_;
    node* parent_;
};

int main() {
    node parent1(string("Parent 1"));
    node parent2(string("Parent 2"));

    node *child1 = parent1.addChild();
    node *child2 = parent2.addChild();

    cout << "Parent of child1: " << child1->parent()->name() << endl;
    cout << "Parent of child2: " << child2->parent()->name() << endl;
    
    return 0;
}
$ ./test 
Parent of child1: Parent 1
Parent of child2: Parent 2

The node class can be used to create a hierarchical structure. It can hold a pointer to its child as well as its parent.

When we’ll create child, we can set the appropriate parent for the child using the this pointer. The addChild() function passes its own object’s pointer to the child object. This pointer is assigned to the parent_ member variable of the child. From the child object, we can access to its parent through this pointer.

In our program we have two child objects – child1 and child2. Each object can refer to its right parent. The two print statements confirmed that.

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

Leave a Reply

Your email address will not be published. Required fields are marked *

0
0
0
0
0
0