How do I refer to an object inside it's own class in c++? [closed]

I am writing an implementation of binary tree in C++. I have written the implementation in Python but I am not able to understand how to refer to an object inside the class in C++. for example, in Python the code to insert a node would be:

def insert( self, val):
    if self.data == val:
        pass
    elif val < self.data:
        if self.left:
            self.left.insert(val)
        else:
            self.left = Node(val)
    else:
        if self.right:
            self.right.insert(val)
        else:
            self.right = Node(val)

but in C++, there is no self object to refer to:

class Node{
public:
    int data;
    Node * leftChild;
    Node * rightChild;

    void insert(int x){
        if ( x == nullptr){
            do stuff
        }
    }
};

What should I insert in place of X to refer to the object of the class itself inside it like the "self" keyword in python ?


Solution 1:

In a member function (like your Node::insert()), all members of the class, e.g. data, are accessible simply by their unqualified names.

The name is accessible without prefix because a (non-static) member function can only be called from an object of the class, e.g. Node n; n.insert(1);. n is the object, and the compiler will interpret data as the data belonging to n.

I don't know Python but I assume that the self parameter corresponds to C++'s implicit this parameter which is available in every non-static member function and points to the object the function is called with, here n. The difference is apparently that this is implicitly passed; it does not appear explicitly in the parameter list. That is a somewhat arbitrary early C++ design decision; Bjarne Stroustrup could as well have made the parameter explicit. The main benefit is a reduction in redundancy (this is always there for a non-static member function, so why mention it?).

Therefore, if you like you can prefix data with this-> to be explicit. That may have some merit for long functions in classes with many members where the casual reader is unsure whether data is a member of local variable or parameter. Some anal coding guidelines require this-> for those reasons, but typically it's only done to resolve ambiguities like name clashes with global variables. A better way to avoid name clashes and recognize members is to require an m... prefix for them, as in mData or m_data, depending on your naming habits.

The code to insert a new value in the tree and not do anything if it's already there looks very much like your Python blueprint:

    void insert(int val){
        if (data == val) 
            return;
        else if (val < data)
            if (left)
                left.insert(val);
            else
                left = Node(val);
        else
            if (right)
                right.insert(val);
            else
                right = Node(val);
    }

This is untested and probably contains typos and perhaps an if/else logic error. In real code I would always curly-brace all code that depends on an if/else, even if it's just one line. That makes maintenance easier: Removing or adding branches here may inadvertently change the association of else blocks or introduce a syntax error.

By the way, the comparison of an integer with a pointer in your original suggestion is weird and does not serve a purpose; generally such comparisons are unusual, and the pointer should be cast to a suitable integer type for that (probably std::intptr_t).