Add C++ example: module7_oop_cpp.cpp
This commit is contained in:
244
src/cpp_examples/module7_oop_cpp.cpp
Normal file
244
src/cpp_examples/module7_oop_cpp.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user