Nested Classes in C++

This article will explain how nested classes and structures work in C++.

Define a class or struct Object Inside Another Class in C++

Sometimes, our classes need so-called helper data types, usually defined as custom struct or class objects. These helper classes can be defined within the other classes, and in such cases, they will be called nested types or nested classes. The latter concept provides many advantages for the programmer, like good scope boundaries and access control.

The following example is shown to demonstrate a simple scenario where we might define a nested class. The main class - CircularList implements a circular linked list, and it needs to define a node which is a composite type, named - ListNode. In this case, the latter is defined in global scope using the struct keyword. Thus, its members are accessible publicly by other classes.

#include <iostream>
#include <string>

using std::string;

struct ListNode {
    struct ListNode *next = nullptr;
    string data;
} typedef ListNode;

class CircularList {
public:
    explicit CircularList(string data) {
        head = new ListNode;
        head->next = head;
        head->data = std::move(data);
        end = head;
    };

    ListNode *insertNodeEnd(string data);
    ListNode *insertNodeHead(string data);
    void printNodes();

    ~CircularList();
private:
    ListNode *head = nullptr;
    ListNode *end = nullptr;
};

int main() {

    return EXIT_SUCCESS;
}

Alternatively, we can move the ListNode definition into the CircularList class. ListNode is not accessible in the global namespace, so we need to include the CircularList:: namespace before the nested class names. Additionally, it is important what access specifier the nested class has, as the usual access control rules apply to them as well.

In this case, ListNode is defined as a public member class, and consequently, it can be accessed from the main function using CircularList::ListNode notation. If a nested class is defined as a protected member, it’s accessible by enclosing class, the latter’s friend classes, and derived classes. On the other hand, a private specifier for a nested class would mean that it’s only accessible within the enclosing class and friend classes.

#include <iostream>
#include <string>

using std::string;

class CircularList {
public:
// Helper Types ->
    struct ListNode {
        struct ListNode *next = nullptr;
        string data;
    } typedef ListNode;

// Member Functions ->
    explicit CircularList(string data) {
        head = new ListNode;
        head->next = head;
        head->data = std::move(data);
        end = head;
    };

    ListNode *insertNodeEnd(string data);
    ListNode *insertNodeHead(string data);
    void printNodes();

    ~CircularList();
private:
    ListNode *head = nullptr;
    ListNode *end = nullptr;
};


int main() {

//    ListNode *n1; // Error
    CircularList::ListNode *n2;

    return EXIT_SUCCESS;
}

Generally, a nested class can have usual access specifiers for its members, and the rules will apply to the enclosing class as regular. Meanwhile, a nested class is not granted any special access to the members of the enclosing class.

Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.

Related Article - C++ Class

  • Object Slicing in C++
  • Call a Destructor Explicitly in C++