C++98corebeginner
Local Classes
C++98 · The Foundation · Compiler flag: -std=c++98
Explanation
A class defined inside a function body, scoped to that function only.
Real-World Scenario
Define a temporary comparator class inside a sorting function.
Quick Snippet
snippet.cpp
void process() { class Helper { public: void run() {} }; Helper h; h.run(); }Full Example
local_classes.cpp
// CodeNebula - C++98 Example: Local Classes
// Compile: g++ -std=c++98 -Wall -Wextra -o example local_classes.cpp
//
// This example demonstrates:
// - Defining a class inside a function (local class)
// - Local classes can access the enclosing function's types and static variables
// - Local classes CANNOT access the function's automatic (local) variables
// - Local classes cannot have static data members
// - Local classes cannot be used as template arguments in C++98
// - Practical uses: ad-hoc comparators, strategy objects, helpers
#include <iostream>
#include <cstring>
// ============================================================
// 1. Basic local class
// ============================================================
void basicLocalClass() {
std::cout << " Inside basicLocalClass():" << std::endl;
// This class exists ONLY inside this function
class Greeter {
private:
char message[64];
public:
Greeter(const char* msg) {
std::strncpy(message, msg, 63);
message[63] = '\0';
}
void greet() const {
std::cout << " Greeter says: " << message << std::endl;
}
};
Greeter g1("Hello from a local class!");
Greeter g2("I only exist in this function.");
g1.greet();
g2.greet();
// Greeter cannot be used outside this function
}
// ============================================================
// 2. Local class accessing enclosing scope
// ============================================================
void accessRules() {
std::cout << " Inside accessRules():" << std::endl;
static int staticVar = 42; // static local -- accessible by local class
int localVar = 100; // automatic local -- NOT accessible (void)
// Suppress unused warning
(void)localVar;
enum Color { RED, GREEN, BLUE }; // local enum -- accessible by local class
class LocalHelper {
public:
void show() const {
// CAN access static variables of the enclosing function
std::cout << " staticVar = " << staticVar << std::endl;
// CAN access local types (enums, typedefs)
Color c = GREEN;
std::cout << " Color GREEN = " << c << std::endl;
// CANNOT access automatic local variables:
// std::cout << localVar; // COMPILE ERROR
}
void modify() {
// Can even modify the static variable
staticVar += 10;
std::cout << " Modified staticVar to " << staticVar << std::endl;
}
};
LocalHelper h;
h.show();
h.modify();
h.show();
}
// ============================================================
// 3. Local class as a strategy / functor
// ============================================================
// Simple sorting function that accepts a comparison interface
class Comparator {
public:
virtual ~Comparator() {}
virtual bool lessThan(int a, int b) const = 0;
};
void bubbleSort(int arr[], int n, const Comparator& cmp) {
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < n - i - 1; ++j) {
if (cmp.lessThan(arr[j + 1], arr[j])) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void sortDemo() {
std::cout << " Inside sortDemo():" << std::endl;
int data[] = { 5, 2, 8, 1, 9, 3 };
int n = 6;
// Local class: ascending comparator
class AscCompare : public Comparator {
public:
bool lessThan(int a, int b) const {
return a < b;
}
};
// Local class: descending comparator
class DescCompare : public Comparator {
public:
bool lessThan(int a, int b) const {
return a > b;
}
};
// Sort ascending
AscCompare asc;
bubbleSort(data, n, asc);
std::cout << " Ascending: ";
for (int i = 0; i < n; ++i) std::cout << data[i] << " ";
std::cout << std::endl;
// Sort descending
DescCompare desc;
bubbleSort(data, n, desc);
std::cout << " Descending: ";
for (int i = 0; i < n; ++i) std::cout << data[i] << " ";
std::cout << std::endl;
}
// ============================================================
// 4. Local class with multiple methods
// ============================================================
void calculatorDemo() {
std::cout << " Inside calculatorDemo():" << std::endl;
class Calculator {
private:
double memory;
public:
Calculator() : memory(0.0) {}
double add(double a, double b) const { return a + b; }
double sub(double a, double b) const { return a - b; }
double mul(double a, double b) const { return a * b; }
double div(double a, double b) const {
if (b == 0.0) {
std::cout << " ERROR: division by zero" << std::endl;
return 0.0;
}
return a / b;
}
void store(double v) { memory = v; }
double recall() const { return memory; }
};
Calculator calc;
std::cout << " 10 + 3 = " << calc.add(10, 3) << std::endl;
std::cout << " 10 - 3 = " << calc.sub(10, 3) << std::endl;
std::cout << " 10 * 3 = " << calc.mul(10, 3) << std::endl;
std::cout << " 10 / 3 = " << calc.div(10, 3) << std::endl;
std::cout << " 10 / 0 = ";
calc.div(10, 0);
calc.store(42.0);
std::cout << " Memory: " << calc.recall() << std::endl;
}
// ============================================================
// 5. Local class restrictions demonstration
// ============================================================
void restrictionsDemo() {
std::cout << " Inside restrictionsDemo():" << std::endl;
class Local {
public:
// static int count; // ERROR: local classes cannot have static data members
int value;
Local(int v) : value(v) {}
// Can have static MEMBER FUNCTIONS (some compilers)
// but cannot have static DATA members
void show() const {
std::cout << " Local value = " << value << std::endl;
}
};
Local a(10);
Local b(20);
a.show();
b.show();
std::cout << " Restrictions:" << std::endl;
std::cout << " - No static data members" << std::endl;
std::cout << " - Cannot access enclosing function's local variables" << std::endl;
std::cout << " - CAN access static local variables and types" << std::endl;
std::cout << " - Cannot be used as template arguments (C++98)" << std::endl;
}
int main() {
std::cout << "========================================" << std::endl;
std::cout << "1. BASIC LOCAL CLASS" << std::endl;
std::cout << "========================================" << std::endl;
basicLocalClass();
// Greeter g("test"); // ERROR: Greeter is not visible here
std::cout << "\n========================================" << std::endl;
std::cout << "2. ACCESS RULES (static vars, types)" << std::endl;
std::cout << "========================================" << std::endl;
accessRules();
std::cout << "\n========================================" << std::endl;
std::cout << "3. LOCAL CLASS AS STRATEGY (sorting)" << std::endl;
std::cout << "========================================" << std::endl;
sortDemo();
std::cout << "\n========================================" << std::endl;
std::cout << "4. LOCAL CLASS WITH MULTIPLE METHODS" << std::endl;
std::cout << "========================================" << std::endl;
calculatorDemo();
std::cout << "\n========================================" << std::endl;
std::cout << "5. LOCAL CLASS RESTRICTIONS" << std::endl;
std::cout << "========================================" << std::endl;
restrictionsDemo();
std::cout << "\n========================================" << std::endl;
std::cout << "6. LOCAL vs NESTED CLASSES" << std::endl;
std::cout << "========================================" << std::endl;
std::cout << " Nested class:" << std::endl;
std::cout << " - Defined inside another CLASS" << std::endl;
std::cout << " - Can be public, private, or protected" << std::endl;
std::cout << " - Accessible via Outer::Inner (if public)" << std::endl;
std::cout << " - Can have static members" << std::endl;
std::cout << std::endl;
std::cout << " Local class:" << std::endl;
std::cout << " - Defined inside a FUNCTION" << std::endl;
std::cout << " - Visible only within that function" << std::endl;
std::cout << " - Cannot have static data members" << std::endl;
std::cout << " - Cannot access enclosing function's local variables" << std::endl;
std::cout << " - Great for one-off helpers, comparators, strategies" << std::endl;
return 0;
}
// Expected output:
// ========================================
// 1. BASIC LOCAL CLASS
// ========================================
// Inside basicLocalClass():
// Greeter says: Hello from a local class!
// Greeter says: I only exist in this function.
//
// ========================================
// 2. ACCESS RULES (static vars, types)
// ========================================
// Inside accessRules():
// staticVar = 42
// Color GREEN = 1
// Modified staticVar to 52
// staticVar = 52
// Color GREEN = 1
//
// ========================================
// 3. LOCAL CLASS AS STRATEGY (sorting)
// ========================================
// Inside sortDemo():
// Ascending: 1 2 3 5 8 9
// Descending: 9 8 5 3 2 1
//
// ========================================
// 4. LOCAL CLASS WITH MULTIPLE METHODS
// ========================================
// Inside calculatorDemo():
// 10 + 3 = 13
// 10 - 3 = 7
// 10 * 3 = 30
// 10 / 3 = 3.33333
// 10 / 0 = ERROR: division by zero
// Memory: 42
//
// ========================================
// 5. LOCAL CLASS RESTRICTIONS
// ========================================
// Inside restrictionsDemo():
// Local value = 10
// Local value = 20
// Restrictions:
// ...
//
// ========================================
// 6. LOCAL vs NESTED CLASSES
// ========================================
// ...comparison...
Run command
g++ -std=c++98 -Wall -Wextra -o example local_classes.cpp