Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Nested Classes ใน C++ (คลาสซ้อน)

Nested Class (คลาสซ้อน) คือ คลาสที่ประกาศ ภายในคลาสอื่น เรียกคลาสภายนอกว่า Enclosing Class

ลักษณะสำคัญ

  • เป็น Member ของ Enclosing Class (เหมือน Variable/Function)
  • มี Access Specifier ของตัวเอง (public/private/protected)
  • Enclosing Class ไม่มีสิทธิ์พิเศษ เข้าถึง private ของ Nested Class
  • Nested Class ไม่มีสิทธิ์พิเศษ เข้าถึง private ของ Enclosing Class
  • Scope: Enclosing::Nested

โค้ดตัวอย่างพื้นฐาน

#include <iostream>
using namespace std;

class Outer {
public:
    class Inner {
    private:
        int num;
    public:
        void setData(int n) { num = n; }
        void showData() { cout << "Number: " << num << endl; }
    };
};

int main() {
    Outer::Inner obj;  // Scope resolution
    obj.setData(9);
    obj.showData();
    return 0;
}

ผลลัพธ์

Number: 9

การเข้าถึงสมาชิก (Access Rules)


class Outer {
private:
    int outerPrivate = 10;
    static int outerStatic;
    
public:
    class Inner {
    public:
        void accessOuter(Outer& o) {
            // cout << o.outerPrivate;  // ❌ Error: ไม่เข้าถึง private ได้
            cout << Outer::outerStatic;  // ✓ static member OK
        }
    };
    
    void accessInner(Inner& i) {
        // cout << i.num;  // ❌ Error: ไม่เข้าถึง private ของ Inner ได้
    }
};

int Outer::outerStatic = 42;

Static Nested Class (C++ ไม่มี static class แต่นิยมเรียกแบบนี้)

ถ้า Nested Class ไม่ต้องการเข้าถึง Non-static Member ของ Outer ให้ทำเป็น ไม่ผูกกับ Instance


class Outer {
public:
    class Nested {
    public:
        static void utility() { cout << "Utility" << endl; }
    };
};

int main() {
    Outer::Nested::utility();  // เรียกได้โดยไม่ต้องมี Outer Object
}

การใช้งานจริง: Iterator Pattern


#include <iostream>
#include <vector>
using namespace std;

class Container {
    vector<int> data;
    
public:
    void add(int v) { data.push_back(v); }
    
    // Nested Iterator Class
    class Iterator {
        const vector<int>& vec;
        size_t index;
    public:
        Iterator(const vector<int>& v, size_t idx) : vec(v), index(idx) {}
        
        int operator*() const { return vec[index]; }
        Iterator& operator++() { ++index; return *this; }
        bool operator!=(const Iterator& other) const { return index != other.index; }
    };
    
    Iterator begin() const { return Iterator(data, 0); }
    Iterator end() const { return Iterator(data, data.size()); }
};

int main() {
    Container c;
    c.add(10); c.add(20); c.add(30);
    
    for (auto it = c.begin(); it != c.end(); ++it)
        cout << *it << " ";  // 10 20 30
    
    // Range-based for ก็ได้ (ถ้ามี begin/end)
    for (int x : c) cout << x << " ";
}

การใช้งานจริง: Node ใน Linked List/Tree


class LinkedList {
private:
    struct Node {  // struct = public by default
        int data;
        Node* next;
        Node(int d) : data(d), next(nullptr) {}
    };
    
    Node* head = nullptr;
    
public:
    void push_front(int val) {
        Node* n = new Node(val);
        n->next = head;
        head = n;
    }
    
    // Nested Class สำหรับ Iterator
    class Iterator {
        Node* current;
    public:
        Iterator(Node* n) : current(n) {}
        int operator*() { return current->data; }
        Iterator& operator++() { current = current->next; return *this; }
        bool operator!=(const Iterator& other) { return current != other.current; }
    };
    
    Iterator begin() { return Iterator(head); }
    Iterator end() { return Iterator(nullptr); }
};

ข้อดีและข้อเสีย

ข้อดี ข้อเสีย
จัดกลุ่ม Logic ที่เกี่ยวข้อง (Encapsulation)เพิ่ม Complexity ของ Class ภายนอก
ควบคุม Visibility (private nested class)Syntax ยุ่งยาก (Outer::Inner::Member)
เข้าถึง Static Members ของ Outer ได้ไม่เข้าถึง Non-static Members ของ Outer ได้โดยตรง
ใช้สร้าง Iterator, Traits, PoliciesCompile time นานขึ้นเล็กน้อย

Local Class (คลาสในฟังก์ชัน) - เปรียบเทียบ


void func() {
    class LocalClass {  // Local to this function
        int x;
    public:
        void set(int v) { x = v; }
    };
    
    LocalClass obj;  // ใช้ได้เฉพาะใน func()
    obj.set(10);
}
// LocalClass ไม่เข้าถึงได้นอก func()

Local Class: จำกัด Scope ใน Function | Nested Class: จำกัด Scope ใน Class