Add module7_oop_in_c.c
This commit is contained in:
225
src/c_examples/module7_oop_in_c.c
Normal file
225
src/c_examples/module7_oop_in_c.c
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
// ============================================
|
||||||
|
// Modul 7: OOP in C (C vs C++ Vergleich)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// OOP IN C (mit Structs und Function Pointers)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
// "Klasse" Point
|
||||||
|
typedef struct Point {
|
||||||
|
// Attribute (private/public durch Convention)
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
|
||||||
|
// "Methoden" als Function Pointer
|
||||||
|
void (*move)(struct Point* self, float dx, float dy);
|
||||||
|
float (*distance_to_origin)(struct Point* self);
|
||||||
|
void (*print)(struct Point* self);
|
||||||
|
} Point;
|
||||||
|
|
||||||
|
// Methoden-Implementierungen
|
||||||
|
void point_move(Point* self, float dx, float dy) {
|
||||||
|
self->x += dx;
|
||||||
|
self->y += dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
float point_distance(Point* self) {
|
||||||
|
return sqrt(self->x * self->x + self->y * self->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void point_print(Point* self) {
|
||||||
|
printf("Point(%.2f, %.2f)\n", self->x, self->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Konstruktor"
|
||||||
|
Point* point_create(float x, float y) {
|
||||||
|
Point* p = malloc(sizeof(Point));
|
||||||
|
p->x = x;
|
||||||
|
p->y = y;
|
||||||
|
p->move = point_move;
|
||||||
|
p->distance_to_origin = point_distance;
|
||||||
|
p->print = point_print;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Destruktor"
|
||||||
|
void point_destroy(Point* p) {
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// "Vererbung" in C (Komposition)
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Point base; // "Vererbt" von Point
|
||||||
|
float z;
|
||||||
|
} Point3D;
|
||||||
|
|
||||||
|
void point3d_move(Point3D* self, float dx, float dy, float dz) {
|
||||||
|
self->base.x += dx;
|
||||||
|
self->base.y += dy;
|
||||||
|
self->z += dz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// Beispiel: Stack als "Klasse"
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
typedef struct Stack {
|
||||||
|
// Private (Konvention: _prefix)
|
||||||
|
int* _items;
|
||||||
|
int _top;
|
||||||
|
int _capacity;
|
||||||
|
|
||||||
|
// Public Interface (Methoden)
|
||||||
|
void (*push)(struct Stack* self, int value);
|
||||||
|
int (*pop)(struct Stack* self);
|
||||||
|
int (*peek)(struct Stack* self);
|
||||||
|
int (*size)(struct Stack* self);
|
||||||
|
void (*destroy)(struct Stack* self);
|
||||||
|
} Stack;
|
||||||
|
|
||||||
|
// Private Methoden
|
||||||
|
static int stack_is_full(Stack* s) {
|
||||||
|
return s->_top == s->_capacity - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stack_is_empty_impl(Stack* s) {
|
||||||
|
return s->_top == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public Methoden
|
||||||
|
void stack_push_impl(Stack* s, int value) {
|
||||||
|
if (stack_is_full(s)) {
|
||||||
|
printf("Stack Overflow!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s->_items[++s->_top] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stack_pop_impl(Stack* s) {
|
||||||
|
if (stack_is_empty_impl(s)) {
|
||||||
|
printf("Stack Underflow!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return s->_items[s->_top--];
|
||||||
|
}
|
||||||
|
|
||||||
|
int stack_peek_impl(Stack* s) {
|
||||||
|
if (stack_is_empty_impl(s)) return -1;
|
||||||
|
return s->_items[s->_top];
|
||||||
|
}
|
||||||
|
|
||||||
|
int stack_size_impl(Stack* s) {
|
||||||
|
return s->_top + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack_destroy_impl(Stack* s) {
|
||||||
|
free(s->_items);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konstruktor
|
||||||
|
Stack* stack_create_oop(int capacity) {
|
||||||
|
Stack* s = malloc(sizeof(Stack));
|
||||||
|
s->_items = malloc(capacity * sizeof(int));
|
||||||
|
s->_top = -1;
|
||||||
|
s->_capacity = capacity;
|
||||||
|
|
||||||
|
// Methoden zuweisen
|
||||||
|
s->push = stack_push_impl;
|
||||||
|
s->pop = stack_pop_impl;
|
||||||
|
s->peek = stack_peek_impl;
|
||||||
|
s->size = stack_size_impl;
|
||||||
|
s->destroy = stack_destroy_impl;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// Vergleich: C++ OOP (als Kommentar)
|
||||||
|
// ============================================
|
||||||
|
/*
|
||||||
|
// C++ Äquivalent:
|
||||||
|
class Point {
|
||||||
|
private:
|
||||||
|
float x, y;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Point(float x, float y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
void move(float dx, float dy) {
|
||||||
|
x += dx;
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance_to_origin() {
|
||||||
|
return sqrt(x*x + y*y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vererbung:
|
||||||
|
class Point3D : public Point {
|
||||||
|
private:
|
||||||
|
float z;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Point3D(float x, float y, float z) : Point(x, y), z(z) {}
|
||||||
|
|
||||||
|
void move(float dx, float dy, float dz) {
|
||||||
|
Point::move(dx, dy);
|
||||||
|
z += dz;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// Hauptprogramm
|
||||||
|
// ============================================
|
||||||
|
int main() {
|
||||||
|
printf("=== Modul 7: OOP in C ===\n\n");
|
||||||
|
|
||||||
|
// Point "Klasse"
|
||||||
|
printf("--- Point (OOP in C) ---\n");
|
||||||
|
Point* p = point_create(3.0, 4.0);
|
||||||
|
p->print(p);
|
||||||
|
printf("Distance: %.2f\n", p->distance_to_origin(p));
|
||||||
|
p->move(p, 1.0, 1.0);
|
||||||
|
p->print(p);
|
||||||
|
point_destroy(p);
|
||||||
|
|
||||||
|
// Stack "Klasse"
|
||||||
|
printf("\n--- Stack (OOP in C) ---\n");
|
||||||
|
Stack* s = stack_create_oop(5);
|
||||||
|
s->push(s, 10);
|
||||||
|
s->push(s, 20);
|
||||||
|
s->push(s, 30);
|
||||||
|
printf("Size: %d\n", s->size(s));
|
||||||
|
printf("Top: %d\n", s->peek(s));
|
||||||
|
printf("Pop: %d\n", s->pop(s));
|
||||||
|
s->destroy(s);
|
||||||
|
|
||||||
|
printf("\n=== Vergleich C vs C++ ===\n");
|
||||||
|
printf("C:\n");
|
||||||
|
printf(" - Structs + Function Pointers\n");
|
||||||
|
printf(" - Manuelle Methoden-Zuweisung\n");
|
||||||
|
printf(" - Keine echten private/public\n");
|
||||||
|
printf(" - Komposition statt Vererbung\n");
|
||||||
|
printf(" - Mehr Boilerplate\n\n");
|
||||||
|
|
||||||
|
printf("C++:\n");
|
||||||
|
printf(" - class keyword\n");
|
||||||
|
printf(" - Automatische Methoden-Bindung\n");
|
||||||
|
printf(" - Echte private/public/protected\n");
|
||||||
|
printf(" - Echte Vererbung (public/private)\n");
|
||||||
|
printf(" - Konstruktor/Destruktor automatisch\n");
|
||||||
|
printf(" - Polymorphie via virtual/override\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user