C OOP คืออะไร
C OOP Object-Oriented Programming struct Function Pointer Encapsulation Inheritance Polymorphism vtable Linux Kernel GObject
| OOP Concept | C++ / Java | C Implementation | Example |
|---|---|---|---|
| Class | class Animal {} | typedef struct Animal {} | struct + typedef |
| Method | void speak() | Function Pointer in struct | void (*speak)(void*) |
| Constructor | Animal() | Animal_create() function | malloc + init |
| Destructor | ~Animal() | Animal_destroy() function | free + cleanup |
| Inheritance | class Dog : Animal | struct Dog { Animal base; } | First member cast |
| Polymorphism | virtual void speak() | Function Pointer + vtable | Override function ptr |
| Encapsulation | private: | 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
ใช้ Struct อย่างไร
typedef struct Type Constructor malloc init Destructor free Function Pointer Method vtable Virtual Table Memory Leak ระวัง
Inheritance ทำอย่างไร
struct ซ้อน Base เป็น First Member Cast pointer Override Function Pointer vtable Dog : Animal Polymorphism Virtual Function
ใช้จริงที่ไหน
Linux Kernel file_operations GObject GTK GNOME SQLite VFS CPython PyObject Apache Module Embedded Systems Hardware Abstraction
สรุป
C OOP struct Function Pointer Encapsulation Opaque Pointer Inheritance First Member Polymorphism vtable Linux Kernel GObject Design Pattern
