Add C++ example: module7_oop_cpp.cpp

This commit is contained in:
2026-04-15 00:18:28 +02:00
parent a7672bbe11
commit 30c1204062

View File

@@ -0,0 +1,244 @@
// ============================================
// C++ Vergleich: Modul 7 - OOP
// Klassen, Vererbung, Polymorphie
// ============================================
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// ============================================
// BASISKLASSE: Shape (abstrakt)
// ============================================
class Shape {
protected:
std::string name_;
std::string color_;
public:
Shape(const std::string& name, const std::string& color)
: name_(name), color_(color) {}
// Virtueller Destruktor (wichtig für Vererbung!)
virtual ~Shape() = default;
// Reine virtuelle Methoden (= abstract in Java)
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual void draw() const = 0;
// Virtuelle Methode (kann überschrieben werden)
virtual std::string info() const {
return color_ + " " + name_;
}
// Nicht-virtuelle Methode
void print_info() const {
std::cout << "Shape: " << info() << "\n"
<< " Area: " << area() << "\n"
<< " Perimeter: " << perimeter() << "\n";
}
};
// ============================================
// ABGELEITETE KLASSE: Circle
// ============================================
class Circle : public Shape {
private:
double radius_;
public:
Circle(double radius, const std::string& color = "red")
: Shape("Circle", color), radius_(radius) {}
// Override (C++11)
double area() const override {
return 3.14159 * radius_ * radius_;
}
double perimeter() const override {
return 2 * 3.14159 * radius_;
}
void draw() const override {
std::cout << "Drawing circle with radius " << radius_ << "\n";
}
// Zusätzliche Methode
double get_radius() const { return radius_; }
};
// ============================================
// ABGELEITETE KLASSE: Rectangle
// ============================================
class Rectangle : public Shape {
private:
double width_;
double height_;
public:
Rectangle(double width, double height, const std::string& color = "blue")
: Shape("Rectangle", color), width_(width), height_(height) {}
double area() const override {
return width_ * height_;
}
double perimeter() const override {
return 2 * (width_ + height_);
}
void draw() const override {
std::cout << "Drawing rectangle " << width_ << "x" << height_ << "\n";
}
// Zusätzliche Methode
bool is_square() const { return width_ == height_; }
};
// ============================================
// KLASSE MIT KOMPOSITION
// ============================================
class Canvas {
private:
std::vector<std::unique_ptr<Shape>> shapes_;
std::string name_;
public:
explicit Canvas(const std::string& name) : name_(name) {}
// Move-Only (kein Kopieren)
Canvas(const Canvas&) = delete;
Canvas& operator=(const Canvas&) = delete;
Canvas(Canvas&&) = default;
Canvas& operator=(Canvas&&) = default;
// Shape hinzufügen (Ownership übernehmen)
void add_shape(std::unique_ptr<Shape> shape) {
shapes_.push_back(std::move(shape));
}
// Polymorphe Iteration
void draw_all() const {
std::cout << "=== " << name_ << " ===\n";
for (const auto& shape : shapes_) {
shape->draw();
}
std::cout << "\n";
}
double total_area() const {
double total = 0;
for (const auto& shape : shapes_) {
total += shape->area();
}
return total;
}
void print_all_info() const {
std::cout << "Canvas contains " << shapes_.size() << " shapes:\n";
for (const auto& shape : shapes_) {
shape->print_info();
std::cout << "\n";
}
}
};
// ============================================
// OPERATOR OVERLOADING
// ============================================
class Complex {
private:
double real_;
double imag_;
public:
Complex(double real = 0, double imag = 0) : real_(real), imag_(imag) {}
// Getter
double real() const { return real_; }
double imag() const { return imag_; }
// Operator überladen
Complex operator+(const Complex& other) const {
return Complex(real_ + other.real_, imag_ + other.imag_);
}
Complex operator*(const Complex& other) const {
return Complex(real_ * other.real_ - imag_ * other.imag_,
real_ * other.imag_ + imag_ * other.real_);
}
// Stream-Operator (friend)
friend std::ostream& operator<<(std::ostream& os, const Complex& c) {
os << c.real_;
if (c.imag_ >= 0) os << "+";
os << c.imag_ << "i";
return os;
}
};
// ============================================
// HAUPTPROGRAMM
// ============================================
int main() {
std::cout << "=== C++ OOP Demonstration ===\n\n";
// 1. Einzelne Objekte
std::cout << "1. Einzelne Shapes:\n";
Circle circle(5.0, "green");
Rectangle rect(4.0, 6.0, "yellow");
circle.print_info();
rect.print_info();
// 2. Polymorphismus
std::cout << "\n2. Polymorphismus:\n";
Shape* shapes[] = {&circle, &rect};
for (auto* shape : shapes) {
shape->draw();
}
// 3. Smart Pointers und Container
std::cout << "\n3. Smart Pointers + Container:\n";
Canvas canvas("My Canvas");
canvas.add_shape(std::make_unique<Circle>(3.0, "red"));
canvas.add_shape(std::make_unique<Rectangle>(5.0, 5.0, "blue"));
canvas.add_shape(std::make_unique<Circle>(2.5, "green"));
canvas.draw_all();
std::cout << "Total area: " << canvas.total_area() << "\n";
// 4. Operator Overloading
std::cout << "\n4. Operator Overloading:\n";
Complex a(3, 4);
Complex b(1, 2);
Complex c = a + b;
Complex d = a * b;
std::cout << "a = " << a << "\n";
std::cout << "b = " << b << "\n";
std::cout << "a + b = " << c << "\n";
std::cout << "a * b = " << d << "\n";
// 5. Vergleich mit C
std::cout << "\n=== C vs C++ OOP ===\n";
std::cout << "C:\n";
std::cout << " - Structs + Function Pointers\n";
std::cout << " - Manuelle vtable-Verwaltung\n";
std::cout << " - Keine Kapselung (nur Convention)\n";
std::cout << " - Manuelle Speicherverwaltung\n\n";
std::cout << "C++:\n";
std::cout << " - class Keyword\n";
std::cout << " - Automatische vtable\n";
std::cout << " - public/private/protected\n";
std::cout << " - Smart Pointers (RAII)\n";
std::cout << " - Operator Overloading\n";
std::cout << " - Templates für generische Klassen\n";
return 0;
}