C OOP คืออะไร

C OOP Object-Oriented Programming struct Function Pointer Encapsulation Inheritance Polymorphism vtable Linux Kernel GObject

OOP ConceptC++ / JavaC ImplementationExample
Classclass Animal {}typedef struct Animal {}struct + typedef
Methodvoid speak()Function Pointer in structvoid (*speak)(void*)
ConstructorAnimal()Animal_create() functionmalloc + init
Destructor~Animal()Animal_destroy() functionfree + cleanup
Inheritanceclass Dog : Animalstruct Dog { Animal base; }First member cast
Polymorphismvirtual void speak()Function Pointer + vtableOverride function ptr
Encapsulationprivate:Opaque Pointer (pimpl)Forward declaration

Struct และ Method

// === OOP in C: Basic Class with Methods ===

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// "Class" definition using struct
typedef struct Animal {
    char name[50];
    int age;
    char type[20];
    // "Methods" using Function Pointers
    void (*speak)(struct Animal* self);
    void (*info)(struct Animal* self);
} Animal;

// "Method" implementations
void Animal_speak(Animal* self) {
    printf("[%s] Generic animal sound!\n", self->name);
}

void Animal_info(Animal* self) {
    printf("Name: %s | Age: %d | Type: %s\n",
           self->name, self->age, self->type);
}

// "Constructor"
Animal* Animal_create(const char* name, int age, const char* type) {
    Animal* a = (Animal*)malloc(sizeof(Animal));
    if (!a) return NULL;
    strncpy(a->name, name, 49);
    a->age = age;
    strncpy(a->type, type, 19);
    // Assign "methods"
    a->speak = Animal_speak;
    a->info = Animal_info;
    return a;
}

// "Destructor"
void Animal_destroy(Animal* self) {
    if (self) {
        printf("Destroying %s\n", self->name);
        free(self);
    }
}

// Usage:
// Animal* cat = Animal_create("Meow", 3, "Cat");
// cat->speak(cat);   // [Meow] Generic animal sound!
// cat->info(cat);    // Name: Meow | Age: 3 | Type: Cat
// Animal_destroy(cat);

Inheritance และ Polymorphism

// === Inheritance & Polymorphism in C ===

// "Derived Class" - Dog inherits from Animal
typedef struct Dog {
    Animal base;  // "Inheritance" - MUST be first member
    char breed[30];
    int tricks_known;
} Dog;

// Override "speak" method
void Dog_speak(Animal* self) {
    Dog* dog = (Dog*)self;  // Safe cast (base is first member)
    printf("[%s] Woof! Woof! (breed: %s)\n",
           self->name, dog->breed);
}

// Dog-specific method
void Dog_fetch(Dog* self) {
    printf("[%s] Fetching the ball! (knows %d tricks)\n",
           self->base.name, self->tricks_known);
}

// Dog "Constructor"
Dog* Dog_create(const char* name, int age,
                const char* breed, int tricks) {
    Dog* d = (Dog*)malloc(sizeof(Dog));
    if (!d) return NULL;
    // Initialize base "class"
    strncpy(d->base.name, name, 49);
    d->base.age = age;
    strncpy(d->base.type, "Dog", 19);
    d->base.info = Animal_info;  // Inherit base method
    d->base.speak = Dog_speak;   // Override with Dog version
    // Initialize Dog-specific fields
    strncpy(d->breed, breed, 29);
    d->tricks_known = tricks;
    return d;
}

// === Polymorphism Demo ===
// void make_all_speak(Animal** animals, int count) {
//     for (int i = 0; i < count; i++) {
//         animals[i]->speak(animals[i]);  // Calls correct version!
//     }
// }
//
// Animal* cat = Animal_create("Kitty", 2, "Cat");
// Dog* dog = Dog_create("Rex", 5, "Labrador", 10);
// Animal* zoo[] = { cat, (Animal*)dog };
// make_all_speak(zoo, 2);
// // [Kitty] Generic animal sound!
// // [Rex] Woof! Woof! (breed: Labrador)

Encapsulation และ Design Pattern

// === Encapsulation with Opaque Pointer ===

// stack.h - Public Interface (Header)
// typedef struct Stack Stack;  // Opaque: ไม่เห็น internals
// Stack* Stack_create(int capacity);
// void Stack_push(Stack* s, int value);
// int Stack_pop(Stack* s);
// int Stack_peek(Stack* s);
// int Stack_is_empty(Stack* s);
// void Stack_destroy(Stack* s);

// stack.c - Private Implementation
// struct Stack {           // Hidden from users
//     int* data;           // Private member
//     int top;             // Private member
//     int capacity;        // Private member
// };
//
// Stack* Stack_create(int capacity) {
//     Stack* s = malloc(sizeof(Stack));
//     s->data = malloc(sizeof(int) * capacity);
//     s->top = -1;
//     s->capacity = capacity;
//     return s;
// }
// void Stack_push(Stack* s, int value) {
//     if (s->top < s->capacity - 1)
//         s->data[++s->top] = value;
// }

// === Real-world: Linux Kernel file_operations ===
// struct file_operations {
//     ssize_t (*read)(struct file*, char*, size_t, loff_t*);
//     ssize_t (*write)(struct file*, const char*, size_t, loff_t*);
//     int (*open)(struct inode*, struct file*);
//     int (*release)(struct inode*, struct file*);
// };
// // Each driver provides its own implementation = Polymorphism!
// static struct file_operations my_fops = {
//     .read = my_read,
//     .write = my_write,
//     .open = my_open,
//     .release = my_release,
// };

เคล็ดลับ

  • First Member: Base struct ต้องเป็น Member แรกเสมอ สำหรับ Inheritance
  • Self: ส่ง self pointer เป็น Argument แรกของทุก Method
  • Naming: ใช้ TypeName_method() Convention เช่น Animal_speak()
  • free: ต้อง free ทุกครั้ง ระวัง Memory Leak
  • Opaque: ใช้ Opaque Pointer สำหรับ Encapsulation ใน Header

OOP ในภาษา C ทำได้ไหม

ได้ ใช้ struct แทน class Function Pointer แทน Method void pointer Polymorphism struct ซ้อน Inheritance Linux Kernel GObject GTK SQLite