Nested & Inner Classes
Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 38 of 104.
A nested class is a class defined inside another class. This technique helps organize code by grouping related types together and can enhance encapsulation by hiding implementation details.
class LinkedList {
public:
class Node { // Nested class
int data;
Node* next;
public:
Node(int d) : data(d), next(nullptr) {}
friend class LinkedList;
};
private:
Node* head;
public:
LinkedList() : head(nullptr) {}
};The nested class Node is tightly coupled to LinkedList - it only makes sense in that context. By nesting it, we signal this relationship and avoid polluting the global namespace with a generic name like "Node".
Nested classes follow the same access rules you've learned. A nested class declared in the private section is only accessible within the outer class.
When declared public, external code can use it with the scope operator:
LinkedList::Node node(42); // Only if Node is publicOne important detail: the nested class doesn't automatically have access to the outer class's private members. They're separate classes that happen to share a namespace.
If the nested class needs access, you must declare it as a friend, as shown in the example above.
Challenge
EasyLet's build a simple task management system where tasks are organized within a project. This is a perfect scenario for nested classes — a Task only makes sense within the context of a Project, so we'll nest it inside to keep our code organized and avoid polluting the global namespace.
You'll create two files to organize your code:
Project.h: Define aProjectclass that contains a nestedTaskclass.Your nested
Taskclass should be declared in the public section ofProjectso it can be accessed from outside. It should store a task name (string) and a completion status (bool). Give it a constructor that takes the name and sets the task as incomplete by default. Include methodscomplete()to mark it done,isComplete()to check its status, andgetName()to retrieve the name.The
Projectclass itself should store a project name (string) and a collection ofTaskpointers. Provide a constructor that takes the project name, a methodaddTask(const std::string& taskName)that creates a new task and adds it to the project, a methodcompleteTask(const std::string& taskName)that finds and completes a task by name, and a methoddisplayStatus()that shows the project name followed by each task's status.Since
Taskis nested insideProject, theProjectclass can work with tasks directly. Don't forget to clean up dynamically allocated tasks in the destructor.main.cpp: Bring everything together by reading a project name and two task names from input (three lines total). Create aProjectwith the given name, add both tasks to it, then display the initial status. Complete the first task and display the status again to show the change.The output format for
displayStatus()should be:Project: <project_name> - <task_name>: [incomplete] - <task_name>: [complete]Use
[complete]or[incomplete]based on each task's status.
This challenge demonstrates how nested classes help organize related types — the Task class is tightly coupled to Project and wouldn't make sense on its own. By nesting it, we signal this relationship clearly in our code structure.
Cheat sheet
A nested class is a class defined inside another class. It helps organize code by grouping related types together and enhances encapsulation.
class LinkedList {
public:
class Node { // Nested class
int data;
Node* next;
public:
Node(int d) : data(d), next(nullptr) {}
friend class LinkedList;
};
private:
Node* head;
public:
LinkedList() : head(nullptr) {}
};Nested classes follow standard access rules. A nested class in the private section is only accessible within the outer class. When declared public, external code can use it with the scope operator:
LinkedList::Node node(42); // Only if Node is publicThe nested class doesn't automatically have access to the outer class's private members. If access is needed, declare it as a friend:
friend class LinkedList;Try it yourself
#include <iostream>
#include <string>
#include "Project.h"
using namespace std;
int main() {
// Read input
string projectName;
string task1Name;
string task2Name;
getline(cin, projectName);
getline(cin, task1Name);
getline(cin, task2Name);
// TODO: Create a Project with the given name
// TODO: Add both tasks to the project
// TODO: Display the initial status
// TODO: Complete the first task
// TODO: Display the status again to show the change
return 0;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesC++ Build & CompilationHeader Files & Source FilesNamespaces & ScopeIntroduction to OOP in C++Classes vs ObjectsThe 'this' PointerMethods (Member Functions)Attributes (Data Members)Ctors & Dtors BasicsRecap - Simple Calculator4Class Properties
Instance vs Static MembersGetters and SettersConst Member FunctionsMutable KeywordStatic Methods and VariablesFriend Functions & ClassesRecap - Bank Account Manager7Inheritance
Basic InheritanceInheritance Access LevelsCtor & Dtor Call OrderMethod OverridingVirtual Functions & VTableMultiple InheritanceVirtual InheritanceRecap - Employee Hierarchy2Memory Management
Stack vs Heap MemoryPointers and ReferencesDynamic Memory (new/delete)Smart Pointers in C++RAII in C++Recap - Dynamic Array Manager5Encapsulation
Access Specifiers in C++Access Specifiers In DepthInformation HidingStruct vs ClassNested & Inner ClassesRecap - Student Records System8Polymorphism
Compile vs Runtime PolymorphFunction OverloadingVirtual Functions RevisitedPure Virtual FunctionsAbstract ClassesInterface Design in C++Dynamic Casting & RTTIRecap - Shape Calculator3Constructors & Destructors
Default ConstructorParameterized ConstructorCopy ConstructorMove ConstructorConstructor Init ListsDelegating ConstructorsDestructor Deep DiveRule of Three / Five / ZeroRecap - String Class6Operator Overloading
Intro to Operator OverloadArithmetic Operator OverloadComparison Operator OverloadStream OperatorsAssignment Operator Overload[] and () Operator OverloadType Conversion OperatorsRecap - Matrix Class9Templates
Function TemplatesClass TemplatesTemplate SpecializationVariadic TemplatesSFINAE & Type Traits BasicsRecap - Generic Container