Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Noch mal Iteratoren ...

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
21.10.2003, 10:00 Uhr
RHBaum



Es scheint sich ja hier jemand auszukennen, also stell ich mal naiv meine Frage:

Zum Hintergrund:
Ich brauche Container, nen ganz bestimmten ADT. Also der Speichertyp ist nen Basiszeiger.
Die Container haben eine bestimmte gemeinsame Basisfunktionalitaet (sie sortieren nach nen bestimmten vordefinierten kriterium) und einige spezielle Funktionaliataeten. (ich brauch zum beispiel nen Container der swapt, weil der Inhalt nie und nimmer in den Speicher gehen wird. und einen fuer kleinere Mengen, der alles im Speicher haelt.)

Die containerklassen selber sind kein Problem. Loese ich intern mit einem oder mehrere std::set. sind aber alle von ner gemeinsammen Schnittselle Abgeleitet.

Fuer den einheitlichen Zugriff braeucht ich dafuer nen generellen bidirectionalen iterator.

Nun meine Fragen:
bekomme ich probleme, wenn ich die funktionalitaeten meines Iterators intern ueber den std::set<>::iterator selbst realisiere ?

Wenn ich meinen Iterator nur auf die Basisschnittstelle aufbaue, bekomme ich probleme mit den positionen, da ja noch keine Impl bekannt ist, kann ich mir keine Positionen merken. Und die Positionen werden abhaengig von der impl sein. Das Element selber als position ist zwar eindeutig, aber nicht performant, wenn man immer wieder von neuem das aus der liste suchen muss.
setz ich den Iterator dierekt an der Container-Impl an, bekomm ich dann probleme, wenn ich den Iterator polymorph nutzen will ??? Oder ists sowieso besser, wenn ich dann nur uber templates gehe ... (mal sehen ob ich das hinbekomme, das ganze sollte eigentlich irgendwann mal fertig kompiliert in ne Lib ... )

Danke schon mal,
Ciao ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.10.2003, 12:43 Uhr
virtual
Sexiest Bit alive
(Operator)


Hm,

keine Ahnung, ob ich Dich richtig verstehe. Daher nochmal so, wie ich es verstanden habe:

C++:
class BaseContainer
{
     virtual Iterator begin() = 0;
     virtual Iterator end() = 0;
};

class ConcreteContainer: public BaseContainer
{
     virtual Iterator begin();
     virtual Iterator end();
};


Scheinbar hast Du eine Basisklasse BaseContainer. Da es ein Container ist, gibt es begin() und end(), die jeweils Iteratoren zurücklieferen. Da BaseContainer abstract ist und wir mal annehmen, begin() und end() seien dort nicht definierbar, können wir nur abstracte Methoden deklarieren. Die Klasse Iterator muß dabei aber auch in der Lage sein, mit einem ConcreteContainer zu arbeiten, weil wir ja keine covariant Returns wollen.
Da Iterator aber niemals by reference zurückgegeben wird, lohnt es sich also nicht, von Iterator eine Ableitung zu machen zu machen; wir müssen also Iterator entweder direkt oder Indirekt in die lage versetzen, mit einem ConcreteContainer zu arbeiten, was aber ziemlich Problematisch wäre, weil es ja auch einen ConcreteContainer2 geben könnte, und dann müsste der auch den ConcreteContainer2 kennen... Ungefähr dieses Problem?

Dann gibt es mehrere Lösungsmöglichkeiten.
Eine besteht darin, der Iterator als Proxyobject zu verwenden:

C++:
class IteratorImpl { };

class Iterator: public std::iterator
{
    IteratorImpl* base;

    Iterator(IteratorImpl* base_) :base(base_) { };
    Iterator::value_type operator * () { return *(*base); };
};

class IteratorForConcreateContainer: public IteratorImpl
{
    ...
};


class ConcreteContainer
{
   ...
   Iterator begin() { return Iterator(new IteratorImp(...)); };
   ...
};


Der Nachteil ist sicherlich, daß Du da einmal mehr dereferenzieren must, ausserdem müssten alle Methoden von IteratorImpl virtuell sein.
Man kann das vielleicht auch über Templates lösen:

C++:
template<class C>
class BaseContainer
{
     typedef typename C::iterator iterator;
     virtual iterator begin() { return iterator(...); } // Setzt einhaitliche Constructoren voraus
     virtual iterator end() { return iterator (...); } // Setzt einhaitliche Constructoren voraus
};

class ConcreteContainer: public BaseContainer<ConcreteContainer>
{
     class iterator
     {
      ...
     };
};


Wenn Du die iterator Klasse in den Containern mit sinnvollen constructoren versiehst, dann kannst Du einfach nur in BaseContainer die begin/end funktionen implementieren; Der Ansatz hier hat den nachteil, daß das Binary nachher größer ist, der Vorteil ist, daß es keinen Performancenachteil gibt.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.10.2003, 13:33 Uhr
RHBaum




Zitat:

Ungefähr dieses Problem?


Genau dieses Problem ... und noch etwas mehr.

es soll eigentlich nen Framework werden, fuer Objecte die die Gleichen Informationen speichen. Zum einem Dateien in unterschiedlichem Format (binaer, XML) zum anderen generische Container, wo man Schnell mal was sortiert ablegen kann( Message Sink) .
Das schlimme ist, wahrscheinlich wollen die Anwender (Modulentwickler) noch nen polymorphen Iterator.

soll dann irgendwie so aussehen ....

C++:
BaseContainer * pList = myAbstractFabrik.getMessageSink() ; // kann ConcreteContainer1 oder ConcreteContainer2 sein, je nach Kontext.
BaseContainer::itarator it = pList->begin();  // er hat keine Ahnung was sein concreter Container ist
while(it != pList->end())
{
BaseObject * pObject = *it; // 2 mal dereferenzieren waer auch ned schlimm, oder Zugriffsfunktionnn
it ++;
}


sowas in der Art sollte gehen .... die Synthax ist eher egal, wenn sie nur einheitlich ist ...

Dieser Post wurde am 21.10.2003 um 13:36 Uhr von RHBaum editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.10.2003, 16:37 Uhr
RHBaum



Hmmm, also bei ner Loesung ueber Templates haeng ich grad fest ...

Problem ist die position ... die Ist Typabhaengig. Und Typinformationen bekomm ich natuerlich ned polymorph ....

Also werd ich nicht drumherumkommen, dein 1. Vorschlag zu realisiern ....

Mal schauen ...

Ciao ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.10.2003, 16:54 Uhr
virtual
Sexiest Bit alive
(Operator)


Das wäre nach Post 002 eh meine Empfehlung gewesen.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: