Eine Vorlage Implementierung könnte wie folgt aussehen:
class Factory {
public:
enum which {
foo, bar, baz
};
template<which w>
A* newA(...);
...
};
template<Factory::which w>
A* Factory::newA(...) {
/* default implementation */
throw invalid_argument();
}
template<>
A* Factory::newA<Factory::foo>(...) {
/* specialization for a 'foo' style A */
...
}
....
Dies erfordert, dass der Wert verwendet, um festzustellen, welche newA
wird zum Zeitpunkt der Kompilierung bekannt sein genannt. Sie könnten möglicherweise einen const char *
als Vorlagenparameter verwenden, aber es ist nicht garantiert, dass er bei allen Compilern funktioniert.
Eine weitere Option besteht darin, Hilfsfabriken zu erstellen, eine für jede Factory-Erstellungsmethode, und diese in der Map zu speichern. Dies ist kein großer Vorteil gegenüber dem Speichern von Methodenzeigern, aber Sie können eine Standarderstellungsmethode definieren und das Abrufen von Objekten aus der Map vereinfachen (Sie müssen nicht überprüfen, ob der Schlüssel vorhanden ist, da Sie eine Standardfactory erhalten). Auf der anderen Seite würde ein Eintrag für jeden unbekannten Schlüssel zur Karte hinzugefügt werden.
Wenn Sie eine enum
anstelle einer Zeichenfolge für den Schlüsseltyp verwenden, müssen Sie sich keine Gedanken darüber machen, ob ein Schlüssel in der Karte vorhanden ist. Es ist zwar möglich, dass jemand einen ungültigen Schlüssel enum
an newA
übergibt, aber er muss das Argument explizit umsetzen, was bedeutet, dass es nicht versehentlich geschieht. Es fällt mir schwer, mir einen Fall vorzustellen, in dem jemand absichtlich einen Absturz verursachen würde in newA
; Die potenziellen Szenarien beinhalten Sicherheit, aber ein Anwendungsprogrammierer könnte die App zum Absturz bringen, ohne Ihre Klasse zu verwenden.
Was ist das übergeordnete Ziel? In den meisten Fällen, in denen Leute Schalter benutzen, ist Polymorphie, was sie verwenden sollten. – outis
+1 das Ersetzen von Schaltern mit Tabellensuchen ist etwas, was ich gerne in dynamischen Sprachen mache. –
Ich habe eine Factory-Klasse, die mehrere Konstruktormethoden haben wird, die Klassen vom Typ A zurückgeben. Die Idee ist, etwas wie A * aClass = Factory-> newA ("key") zu machen; . Dann verwendet die Factory den "Schlüssel", um die korrekte Methode zum Erstellen einer A-Klasse aufzurufen, und gibt sie entsprechend zurück. – Goles