Hallo Simon,
Einiges hatte ich auch schon so, wie du es vorgeschlagen hast,
wie z. B. die Klasse „DVD“ und eine zweite Klasse, in der die
DVDs als Vektor gespeichert sind. Genau so die Methode zum
Hinzufügen einer DVD und hier sollte auch die Methode zum
Suchen untergebracht werden.
…
…
Ich werde jetzt gleich versuchen, die Suche so umzusetzten,
wie du es beschrieben (nachdem ich erstmal google, was ein
Iterator ist).
Ein „Iterator“ ist faktisch ein „Zeiger“, mit dem man
über die Elemente eines STL-Containers laufen kann,
z.B. über std::vector. Und da die von mir vorgeschlagene
„DVDListe“ ein vector ist, geht das ohne weiteres.
In der besagten Funktion in der Klasse „DVDSammlung“:
...
DVDListe suche\_nach(const Anfrage& suchbedingung) {
DVDListe resultat;
1: for(DVDListe::const\_iterator it=begin(); it!=end(); it++)
2: if( suchbedingung(\*it) )
3: resultat.push\_back(\*it);
return resultat;
}
...
bezieht sich das „begin()“ auf den vector selbst, der
diese eine Elementfunktionen (begin,end) besitzt:
...
class DVDSammlung : public DVDListe {
...
sprich: DVDListe ist ja ein vector und hat
das begin() und end() von einem std::vector be-
kommen. DVDSammlung *ist* damit auch ein vector.
Beide Funktionen (begin,end) liefern so einen Iterator,
den auf den Anfang und den *hinter* dem letzten Element.
Die Elemente dieses vector sind jeweils
ein Element der Klasse DVD, da ein Iterator ein
Zeiger ist, muß man ihn dereferenzieren (mit ‚*‘).
Die Hilfsklasse „Anfrage“ (mit der übergebenen
Variablen „suchbedingung“) hat im obigen beispiel
einen
...
bool operator() (const DVD& dvd) { return passt/passt nicht ... }
...
sprich: wenn da steht:
...
if( suchbedingung(\*it) ) ...
...
wird eigentlich aufgerufen:
...
if( Anfrage::suchbedingung.operator()(\*it) ) ...
...
Das ist das sog. Operator-Overloading.
In so einer überladenen Operatorfunktion kann
man dann den eigentlichen Vergleich verstecken:
...
class Anfrage : public pair {
public:
Anfrage(DVD::SuchFeld f, const string& s) : pair(f, s) {}
bool operator() (const DVD& dvd) const { return dvd.ElementVon(first) == second; }
};
...
Hier hatte ich mir überlegt, daß die Klasse DVD einfach
eine zusätzliche Funktion „ElementVon(welchesAttribut)“
bekommt, welche dann anhand eines „enums“ entscheidet,
was abgefragt wird:
...
class DVD {
...
public:
enum SuchFeld { TITEL, GENRE, BESCHREIBUNG };
...
...
string ElementVon(SuchFeld suchfeld) const {
switch(suchfeld) {
case TITEL: return m\_titel;
case GENRE: return m\_genre;
case BESCHREIBUNG: return m\_beschreibung;
default: return "Fehler!";
}
}
...
usw. Der Anfrage::operator()(DVD&:wink: würde dann den
Vergleich mit der Rückgabe der DVD::ElementVon()
durchführen.
Viele Grüße
CMБ