Nested Classes in C++

Jinku Hu Oct 12, 2023
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.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ Class