Erstens ist die "STL" kein offizieller Begriff, sondern der Name der Bibliothek, die für die Aufnahme in die C ++ - Standardbibliothek vorgeschlagen wurde, wenn keine Container vorhanden waren. Es bietet im Wesentlichen Container- und Algorithmusvorlagen.
Diese Container- und Algorithmusvorlagen sind ... Vorlagen, sodass sie nach Bedarf Typen erzeugen. Sie sind aus Sicht des Benutzers nicht auf Vererbung angewiesen.
Die Standardbibliothek gibt jedoch im Wesentlichen die Schnittstelle der Bibliothek an, nicht die Implementierung. Viele STL-Implementierungen verwenden ein wenig Objektorientierung in ihrer Implementierung, aber als Benutzer werden Sie es nicht sehen, wenn Sie nicht in den Quellcode Ihrer Implementierung eintauchen (der verfügbar gemacht werden muss, da es sich im Wesentlichen um Vorlagencode handelt).
Ich habe erfahren, dass die Funktion eines virtuellen Mitglieds, die die OO rechtfertigt, der Vorlage widerspricht. Ist das richtig?
Nein, es handelt sich um orthogonale Konzepte, die sehr unterschiedliche Vor- und Nachteile bieten. In C ++ besteht einer der Hauptvorteile bei der Verwendung einer solchen Sprache darin, dass Sie sowohl verfügbar sind als auch eine verwenden und nicht mit der anderen abbrechen. Es ist sogar ein sehr großer Vorteil. Eine der interessantesten Redewendungen in C ++ ist beispielsweise CRTP , das sowohl Vorlagen als auch Vererbung verwendet. Die Idee ist, dass Sie mit dem Vererbungsteil mehrere Typen mit einem gemeinsamen Verhalten und gemeinsamen Daten als Basisklasse erweitern können. Während der Vorlagenteil sicherstellt, dass für jedes untergeordnete Element bestimmte Basisklassen generiert werden, ist es unmöglich, einen Zeiger auf alle Klassen zu haben, die die CRTP-Klasse als Basis verwenden. Dies ist äußerst nützlich und erlaubt es nicht, mit der Vererbung herumzuspielen, wo es keine geben sollte.
Ich habe auch sehr generische Ereignisverteilungssysteme implementiert, die weder Ereignistypen noch Listenertypen kannten, sondern intern dynamischen und statischen Code kombinierten, der es zusammen ermöglichte, die richtigen internen Typen zu generieren, die den richtigen Laufzeittypen entsprechen.
Und das ist der Punkt: Sie brauchen nicht immer "Objektorientierung". Tatsächlich müssen Sie die meiste Zeit, wenn Sie sie überhaupt nicht benötigen, einige Typen definieren und sie direkt als unterschiedlichen Teil einer abstrakten Engine (Komposition) verwenden. Sie benötigen nicht immer generischen Code, auch Vorlagen genannt. Manchmal muss eine Funktion verallgemeinert werden, um sie auf mehrere nicht verwandte Typen anzuwenden. Wenn sie verwandt sind, können Sie stattdessen ihre Basisklasse verwenden und benötigen keine Vorlagen.
Sie haben unterschiedliche Vorteile und völlig unterschiedliche Kosten, sodass sie gut kombiniert werden können, um komplexe Probleme zu lösen.
STL ist ein gutes Beispiel für ein Problem, bei dem es hauptsächlich darum geht, Typen (Container) und Funktionen (Algorithmen) bereitzustellen, die sich auf einen bestimmten Typ beziehen, anstatt auf eine Hierarchie von Laufzeitobjekten. In der Standardbibliothek werden Streams auf eine für die Objektorientierung typische Weise erstellt: Es handelt sich um eine Hierarchie von Stream-Klassen, die verschiedene Funktionen ausführt, um eine Sub-Stream-Klasse zu definieren, die unterschiedliche Verhaltensweisen / Kapazitäten kombiniert. Dort ist die Objektorientierung nützlich, auch wenn einige Leute es vorziehen würden, wenn sie eher der STL ähnelt (ich bin kein Spezialist auf diesem Gebiet).
Stellen Sie sich diese also als sehr unterschiedliche Werkzeuge vor, als Schraubenzieher und Hammer. In C ++ können Sie nicht nur an ein Tool denken.