Entwurfsmuster in C++ mit Beispielen: Vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Entwurfsmuster in C++ mit Beispielen: Von A bis Z



Entwurfsmuster (Design Patterns) sind bewährte Lösungen für typische Probleme, die bei der Softwareentwicklung auftreten. Für C++ sind diese Muster besonders wichtig, da die Sprache objektorientierte, generische und hardwarenahe Programmierung vereint. In diesem Artikel behandeln wir die wichtigsten Entwurfsmuster in C++ mit Codebeispielen, die Ihnen helfen, flexibleren, wiederverwendbaren und wartbareren Code zu schreiben.



Wir betrachten die drei Hauptkategorien von Mustern nach der GoF-Klassifikation (Gang of Four): Erzeugungs-, Struktur- und Verhaltensmuster. Jedes Muster wird mit einem realen Beispiel in C++ veranschaulicht.



1. Erzeugungsmuster (Creational Patterns)



Erzeugungsmuster abstrahieren den Prozess der Objekterzeugung und machen das System unabhängig davon, wie Objekte erstellt, zusammengesetzt und dargestellt werden.



1.1. Singleton (Einzelstück)



Singleton stellt sicher, dass eine Klasse nur eine Instanz hat, und bietet einen globalen Zugriffspunkt darauf. In C++ wird es oft über ein statisches lokales Objekt implementiert (thread-safe seit C++11).



class Logger {public:    static Logger& getInstance() {        static Logger instance; // Thread-sichere Initialisierung        return instance;    }

void log(const std::string& message) { std::cout << "[LOG] " << message << std::endl; }

private: Logger() = default; Logger(const Logger&) = delete; Logger& operator=(const Logger&) = delete;};

// Verwendungint main() { Logger::getInstance().log("Anwendung gestartet"); return 0;}


Wann verwenden: Konfigurationsverwaltung, Thread-Pools, Logging-Systeme.



1.2. Factory Method (Fabrikmethode)



Factory Method definiert eine Schnittstelle zur Erstellung eines Objekts, überlässt es aber den Unterklassen, zu entscheiden, welche Klasse instanziiert wird.



class Product {public:    virtual void use() = 0;    virtual ~Product() = default;};

class ConcreteProductA : public Product {public: void use() override { std::cout << "Produkt A" << std::endl; }};

class ConcreteProductB : public Product {public: void use() override { std::cout << "Produkt B" << std::endl; }};

class Creator {public: virtual Product* createProduct() = 0; void someOperation() { Product* p = createProduct(); p->use(); delete p; } virtual ~Creator() = default;};

class CreatorA : public Creator {public: Product* createProduct() override { return new ConcreteProductA(); }};

class CreatorB : public Creator {public: Product* createProduct() override { return new ConcreteProductB(); }};


Wann verwenden: Wenn eine Klasse nicht weiß, Objekte welcher Unterklassen sie erstellen muss.



2. Strukturmuster (Structural Patterns)



Strukturmuster beschreiben, wie Klassen und Objekte zu größeren Strukturen zusammengefasst werden können, wobei Flexibilität und Effizienz erhalten bleiben.



2.1. Adapter (Adapter)



Adapter ermöglicht es Objekten mit inkompatiblen Schnittstellen, zusammenzuarbeiten. In C++ wird es oft durch Vererbung oder Komposition implementiert.



// Ziel-Schnittstelleclass Target {public:    virtual void request() const {        std::cout << "Normale Anfrage" << std::endl;    }    virtual ~Target() = default;};

// Anpassbare Klasseclass Adaptee {public: void specificRequest() const { std::cout << "Spezifische Anfrage" << std::endl; }};

// Adapter (durch Komposition)class Adapter : public Target {private: Adaptee* adaptee_;public: Adapter(Adaptee* a) : adaptee_(a) {} void request() const override { adaptee_->specificRequest(); }};

Blogs

Buchempfehlungen