c++ - Sollte ich in diesem Fall verschachtelte Klassen verwenden?

Translate

Ich arbeite an einer Sammlung von Klassen für die Videowiedergabe und -aufnahme. Ich habe eine Hauptklasse, die sich wie die öffentliche Schnittstelle verhält, mit Methoden wieplay(), stop(), pause(), record()etc ... Dann habe ich Arbeitspferdeklassen, die die Videodekodierung und Videokodierung durchführen.

Ich habe gerade von der Existenz verschachtelter Klassen in C ++ erfahren und bin gespannt, was Programmierer über deren Verwendung denken. Ich bin ein wenig vorsichtig und nicht wirklich sicher, was die Vor- und Nachteile sind, aber sie scheinen (laut dem Buch, das ich lese) in Fällen wie meinem verwendet zu werden.

Das Buch schlägt vor, dass in einem Szenario wie meinem eine gute Lösung darin besteht, die Arbeitspferdeklassen in der Schnittstellenklasse zu verschachteln, sodass es keine separaten Dateien für Klassen gibt, die der Client nicht verwenden soll, und mögliche Namenskonflikte zu vermeiden. Ich weiß nichts über diese Rechtfertigungen. Verschachtelte Klassen sind für mich ein neues Konzept. Ich möchte nur sehen, was Programmierer über das Problem denken.

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Ich würde hier nur ungern verschachtelte Klassen verwenden. Was wäre, wenn Sie eine abstrakte Basisklasse für einen "Multimedia-Treiber" für das Back-End-Material (Arbeitspferd) und eine separate Klasse für die Front-End-Arbeit erstellen würden? Die Front-End-Klasse könnte einen Zeiger / Verweis auf eine implementierte Treiberklasse (für den entsprechenden Medientyp und die entsprechende Situation) verwenden und die abstrakten Operationen an der Arbeitspferdestruktur ausführen.

Meine Philosophie wäre es, beide Strukturen dem Kunden auf polierte Weise zugänglich zu machen, nur unter der Annahme, dass sie zusammen verwendet werden.

Ich würde so etwas wie einQTextDocumentin Qt. Sie bieten eine direkte Schnittstelle zur Verarbeitung von Bare-Metal-Daten, geben die Berechtigung jedoch an ein Objekt wie ein QTextEdit weiter, um die Manipulation durchzuführen.

Quelle
Translate

Sie würden eine verschachtelte Klasse verwenden, um eine (kleine) Hilfsklasse zu erstellen, die zum Implementieren der Hauptklasse erforderlich ist. Oder um beispielsweise eine Schnittstelle zu definieren (eine Klasse mit abstrakten Methoden).

In diesem Fall besteht der Hauptnachteil verschachtelter Klassen darin, dass dies die Wiederverwendung erschwert. Vielleicht möchten Sie Ihre VideoDecoder-Klasse in einem anderen Projekt verwenden. Wenn Sie es zu einer verschachtelten Klasse von VideoPlayer machen, können Sie dies nicht auf elegante Weise tun.

Fügen Sie stattdessen die anderen Klassen in separate .h / .cpp-Dateien ein, die Sie dann in Ihrer VideoPlayer-Klasse verwenden können. Der Client von VideoPlayer muss nur noch die Datei enthalten, die VideoPlayer deklariert, und muss immer noch nicht wissen, wie Sie es implementiert haben.

Quelle
Translate

Eine Möglichkeit, zu entscheiden, ob verschachtelte Klassen verwendet werden sollen oder nicht, besteht darin, zu überlegen, ob diese Klasse eine unterstützende Rolle spielt oder eine eigene Rolle spielt.

Wenn es nur existiert, um einer anderen Klasse zu helfen, mache ich es im Allgemeinen zu einer verschachtelten Klasse. Es gibt eine ganze Menge Vorbehalte, von denen einige widersprüchlich erscheinen, aber alles hängt von Erfahrung und Bauchgefühl ab.

Quelle
Translate

klingt wie ein Fall, in dem Sie die verwenden könntenStrategiemuster

Quelle
Translate

Manchmal ist es angebracht, die Implementierungsklassen vor dem Benutzer zu verbergen. In diesen Fällen ist es besser, sie in einer foo_internal.h abzulegen als in der öffentlichen Klassendefinition. Auf diese Weise werden die Leser Ihrer foo.h nicht sehen, was Sie bevorzugen, und sie können trotzdem Tests für jede der konkreten Implementierungen Ihrer Schnittstelle schreiben.

Quelle
Translate

Wir haben ein Problem mit einem halb alten Sun C ++ - Compiler und der Sichtbarkeit verschachtelter Klassen festgestellt, deren Verhalten sich im Standard geändert hat. Dies ist natürlich kein Grund, Ihre verschachtelte Klasse nicht zu absolvieren. Beachten Sie dies nur, wenn Sie Ihre Software auf vielen Plattformen einschließlich alter Compiler kompilieren möchten.

Quelle
Translate

Wenn Sie in Ihrer Interface-Klasse Zeiger auf Ihre Arbeitspferdeklassen verwenden und diese nicht als Parameter oder Rückgabetypen in Ihren Schnittstellenmethoden verfügbar machen, müssen Sie die Definitionen für diese Arbeitspferde nicht in Ihre Schnittstellenheaderdatei aufnehmen (Sie nur vorwärts deklarieren sie stattdessen). Auf diese Weise müssen Benutzer Ihrer Benutzeroberfläche nichts über die Klassen im Hintergrund wissen.

Sie müssen dafür definitiv keine Klassen verschachteln. In der Tat machen separate Klassendateien Ihren Code viel lesbarer und einfacher zu verwalten, wenn Ihr Projekt wächst. Es hilft Ihnen auch später, wenn Sie eine Unterklasse benötigen (z. B. für verschiedene Inhalte / Codec-Typen).

Hier finden Sie weitere Informationen zumPIMPL-Muster(Abschnitt 3.1.1).

Quelle
Translate

Sie sollten eine innere Klasse nur verwenden, wenn Sie sie nicht als separate Klasse über die öffentliche Schnittstelle der potenziellen äußeren Klasse implementieren können. Innere Klassen erhöhen die Größe, Komplexität und Verantwortung einer Klasse, sodass sie sparsam eingesetzt werden sollten.

Ihre Encoder / Decoder-Klasse scheint besser zu passenStrategiemuster

Quelle
Vanessa Lee
Translate

Ein Grund, verschachtelte Klassen zu vermeiden, besteht darin, dass Sie den Code jemals mit swig (http://www.swig.org) zur Verwendung mit anderen Sprachen. Swig hat derzeit Probleme mit verschachtelten Klassen, sodass die Schnittstelle zu Bibliotheken, die verschachtelte Klassen verfügbar machen, zu einem echten Problem wird.

Quelle
Translate

Eine andere Sache, die Sie beachten sollten, ist, ob Sie sich jemals unterschiedliche Implementierungen Ihrer Arbeitsfunktionen vorstellen (z. B. Dekodieren und Kodieren). In diesem Fall möchten Sie auf jeden Fall eine abstrakte Basisklasse mit verschiedenen konkreten Klassen, die die Funktionen implementieren. Es wäre nicht wirklich angebracht, für jeden Implementierungstyp eine eigene Unterklasse zu verschachteln.

Quelle