Scoping and this in c++

As a course producer for USC’s CSCI 104 students will often ask me questions about stuff I don’t know or didn’t think about. It makes me feel a little dumb for a moment but then we’ll both look into it together and I’ll learn something new! Today, someone about the keyword this in c++ that made me realize I wasn’t as certain about what the keyword did myself. In the last assignment of the semester, we implement a couple different types of self-balancing binary-search-trees (these are AVL trees and splay trees). These are built on a base class that includes the basic functionality of insert, find, and the destructor. All classes use a generic type of node and add additional features for trees that balance using a height property versus a recently-used property. Since each of the trees have overriding functions and member variables, it’s good to know how to access exactly what you want to in a given class.

Let’s introduce a couple of friends, the this keyword and class::scoping.

The keyword this is a pointer to the current object. If I’m implementing some class BinarySearchTree, then anytime I use this inside my class, this is type BinarySearchTree *. The pointer can be used to access members of my class. If I’ve inherited functions from another class, I can access a superclass’ members by scoping with that class name.

Let’s say we have a base class A that has a root member variable. This class will have a couple of useless getter and setter functions for example.


class A {
    public:
    int root = 'A';

    void setSuperRoot(int val){
        root = val;
    }

    int getSuperRoot(){
        return root;
    }
};

Class A will have a child class B that automatically inherits those functions which are now automatically accessible to any class B objects. Now if we want to access any members of A specifically, we use scoping to access them. Here, the example is to access the root value: A::root.


class B : public A {
    public:

    int root = 'B';

    // setSuperRoot() and getSuperRoot() are inherited in this class
    // and specifically change A::root.

    void setRootThis(int val){
        // this keyword is unnecessary here
        this->root = val;
    }

    void setRoot(int val){
        // set root implicitly uses the this keyword
        // to refer to the root in the current class
        root = val;
    }
    int getRoot(){
        return root;
    }

    int getThisRoot(){
        return this->root;
    }

    int getSuperRootB(){
        // to access the root member of superclass A, use scoping!
        return A::root;
    }
};

Here’s all the code showing how each function modifies the child and parent class’ versions of member variable root.


#include <iostream>
using namespace std;

class A {
    public:
    int root = 'A';
    void setSuperRoot(int val){ root = val; }
    int getSuperRoot(){ return root; }
};

class B : public A {
    public:
    int root = 'B';

    void setRootThis(int val){ this->root = val; }
    void setRoot(int val){ root = val; }
    int getRoot(){ return root; }
    int getThisRoot(){ return this->root; }
    int getSuperRootA(){ return A::root; }
};

int main(){

    B b;
    b.setRootThis(7);

    cout << "B root: " << b.getRoot();              // prints 7
    cout << " B this->root: " << b.getThisRoot();   // prints 7
    cout << " A root: " << b.getSuperRootA()        // prints 65
                                                    // (A::root's initial value)
    cout << "\n";

    b.setRoot(2);

    cout << "B root: " << b.getRoot();              // prints 2
    cout << " B this->root: " << b.getThisRoot();   // prints 2
    cout << " A root: " << b.getSuperRootA()        // prints 65
    cout << "\n";

    b.setSuperRoot(42);

    cout << "B root: " << b.getRoot();              // prints 2 (value unchanged)
    cout << " B this->root: " << b.getThisRoot();   // prints 2
    cout << " A root: " << b.getSuperRootA()        // prints 42
    cout << "\n";
}

I highly recommend reviewing the docs about this for a more in-depth tour of what this means in c++ and when its use is required.

2019

Debugging weird c++ behavior

2 minute read

Sometimes you’ll have a program that seems to work but will produce a ton of Valgrind errors. You’ll get some fairly strange errors about invalid reads or co...

Scoping and this in c++

3 minute read

As a course producer for USC’s CSCI 104 students will often ask me questions about stuff I don’t know or didn’t think about. It makes me feel a little dumb f...

SQL Join Guide

3 minute read

I’m working on a project at my internship right now that has helped me learn a lot about SQL, mainly through making some stupid mistakes. This article focuse...

Redis Basics

4 minute read

The name redis comes from RE mote DI ctionary S torage, which is a good description of what redis is: a fast, key-value data structure. Redis is an in-memory...

Using the name variable in Python

1 minute read

When writing modules in python, it’s nice to test individual components. You can always add some messy test cases at the bottom of your code but, of course, ...

Getting Help in Vim

less than 1 minute read

The :help command in Vim is possibly the most powerful one of all. I agree with Romain Lafourcade of this handy website about that.

Customizing your Bash prompt

2 minute read

Your terminal can be customized in several different ways including how your prompt appears. You can color code shell variables such as your username and dir...

Basic Bash Backup

1 minute read

I spent most of early Saturday morning finishing up my backup scripts and debugging Bash. One could say I was, Bashing my head against the wall. No need to ...

Back to Top ↑