-4

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 ?

  • 8
    I highly recommend you invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) if you're serious about learning C++. – Some programmer dude Jan 20 '22 at 11:58
  • 1
    Whatever you’re using to learn C++, book, class, etc, should cover this early on. Consider finding a better source. – Biffen Jan 20 '22 at 11:59
  • 2
    This subject matter should be covered in an introductory chapter in every C++ textbook. Is there something in your C++ textbook's explanation, of this, that's unclear to you? C++ is the most complicated and hardest to learn programming language in use today, and it's just not practical to learn it by asking one basic question, at a time, on a web site. Unfortunately, Stackoverflow will not be a good replacement for a textbook. – Sam Varshavchik Jan 20 '22 at 11:59
  • 1
    roughly speaking `self` is called `this` in C++, but this analogy is only of limited use, as python and C++ are very different in details – 463035818_is_not_an_ai Jan 20 '22 at 11:59
  • 1
    `this->leftChild` keyword. You better grab a good beginner C++ book and read it. – digito_evo Jan 20 '22 at 11:59
  • 1
    Python (by convention) uses `self` for `self.data`. C++ uses `this` which is a keyword for `this->data`, but usually in the context where it is accessed the `this->` is unnecessary and typically omitted. – Eljay Jan 20 '22 at 11:59
  • 2
    There is no need to self reference. from within a class you can access members by their name, thus leftChild, (only in some exotic cases with class templates you will need to use this self reference : this->). A link to get you you started : https://www.learncpp.com/cpp-tutorial/classes-and-class-members/ – Pepijn Kramer Jan 20 '22 at 11:59

1 Answers1

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).

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62