zeiger auf unterschiedliche STL-container in einem array?
-
Hallo allerseits...
Ich habe hier ein verständnisproblem mit den STL-containern wie <vector> <list> <queue> <deque> <stack> usw. ...
Und zwar verstehe ich nicht, warum sich die entwickler von diesen template-klassen die mühe gegeben haben, all diesen containern dieselbe user-interface zu verpassen (iteratoren gibts überall, begin() end() * ++ usw, mehr brauche ich auch gar nicht...) sie jedoch trotzdem nicht von irgendeinen abstrakten klasse abgeleitet haben?So sehen die zwar für den benutzer alle gleich aus, und lassen sich auch in den ganzen vordefinierten template-algorithmen auf die gleiche art und weise verwenden, aber die sind, soweit ich das alles richtig verstanden habe, nicht direkt polymorph, d.h. dass ich zB kein array von zeigern auf eine abstrakte "stl_container" klasse anlegen kann, wo ich dann zeiger auf <list> und <vector> gleichzeitig speichern kann.
Wüsste jemand, wie man das geschickt umgehen kann?
Letztendlich ist es mein ziel, irgendwie zeiger auf verschiedene container zu speichern, und sie alle dann auf die gleiche art und weise zu behandeln.
Vielen dank im voraus.
-
Kannste nur in ein anderes Objekt kapseln und an das eigentliche Objekt weiterleiten...
-
Kannst eine Basisklasse schreiben und dann eine Kindklasse welche einen Container als Templateparameter nimmt. Danach musst du das gleiche Spiel dann noch für die Iteratoren machen. (Gibt für die Iteratoren auch etwas fertiges google mal nach "any_iterator" + "Adobe".)
Den Sinn davon erschließt sich mir aber nicht...
-
Andrey schrieb:
...die sind, soweit ich das alles richtig verstanden habe, nicht direkt polymorph,...
Doch !
Allerdings eben per Compilezeitpolymorphie und nicht per Laufzeitzeitpolymorphie ... templates eben. Mit all den Vor- und Nachteilen, die das hat. Allerdings kann man sich die Frage stellen, ob die C++-Standardlib nicht auch "laufzeitpolymorphe Container" hätte zur Verfügung stellen können.
Einen anderen "Trick", das zu umgehen, habe ich leider auch nicht für Dich.
Gruß,
Simon2.
-
also, danke schon mal für die ideen...
ich habe hier versucht, das was Ben04 vorgeschlagen hat, in einem kleinen beispielprogramm umzusetzen. Folgendes ist dabei rausgekommen:
Fehlerhaft 
#include <iostream> //abstract BaseWrapper class as interface for all child classes class BaseWrapper{ public: virtual void saySomething()=0; }; //template specified wrapper, that can storage pointers of any type template <class C> class SpecifiedWrapper : BaseWrapper{ public: C* pWrappedObject; //constructor SpecifiedWrapper(C* pToBeWrapped){ pWrappedObject=pToBeWrapped; } void saySomething(){ pWrappedObject->saySomething(); } }; //this symbolizes the different container classes class Example1{ public: Example1(){}; void saySomething(){ std::cout<<"i'm an object of type -1-"; } }; class Example2{ public: Example2(){}; void saySomething(){ std::cout<<"i'm an object of type -2-"; } }; //array filled with (wrapper-objects)* BaseWrapper* wrapperArray[10]; //function, that wraps the passed object pointer and adds it to the array template <class C> void addWrappedObjectToArray(C* pToBeWrapped, int pos){ SpecifiedWrapper<C>* pWrapper=new SpecifiedWrapper<C>(pToBeWrapped); if(pos>=0 && pos<10){ wrapperArray[pos]=pWrapper; //polymorph!!! } } int main(){ Example1 ex1=Example1(); Example2 ex2=Example2(); Example1 ex3=Example1(); //... addWrappedObjectToArray(&ex1, 0); addWrappedObjectToArray(&ex2, 1); addWrappedObjectToArray(&ex3, 2); //now look whats in the array... (*wrapperArray[0]).saySomething(); (*wrapperArray[1]).saySomething(); (*wrapperArray[2]).saySomething(); return 0; }ja, ich weiß, es ist ein bissl viel und ein bissl finster... Deswegen ein paar erläuterungen:
BaseWrapper ist die basis-hüllen-klasse, die ein einheitliches interface bereitstellen und laufzeitpolymorphie gewährleisten soll. Von der ist dann die template classe SpecifiedWrapper abgeleitet, die eigentlich Zeiger auf alle möglichen objekte speichern kann und die funktion saySomething() realisiert.
Die beiden example-klassen ersetzen im beispiel die container.
Dann gibts noch ein array aus BaseWrapper*-zeigern, wo eigentlich jede beliebige zeiger auf SpecifiedWrapper ebenfalls gespeichert werden dürften (das ist doch der sinn bei der polymorphie, oder liege ich da total falsch?).Naja... Bei der funktion addWrappedObjectToArray(...){/* ... */} geht dann alles schief... Der compiler spuckt zwei fehler und die meldungen
Konvertierung von 'class SpecifiedWrapper<class Example1> *' zu 'class BaseWrapper *' existiert bereits, aber es ist kei
n Zugriff darauf moeglichund
Siehe Verweis auf Instantiierung der kompilierten Funktionsvorlage 'void __cdecl addWrappedObjectToArray(class Example1 *,int)'
aus, aber leider kann ich damit wenig anfangen...
Wäre jemand so nett
a) sich den ganzen mist durchzulesen
b) mir zu sagen was die fehler heissen, und wodurch die verursacht werden
c) und evtl wie ich sie behebeDanke schön

-
Also so ganz kannst du die STL Container nicht unter einen Hut bringen, denn sie sind alle leicht unterschiedlich:
http://www.linuxsoftware.co.nz/cppcontainers.html
-
*kurz den Text überfliegt* Der Fehler wurde verursacht durch ein fehlendes Wort: "class SpecifiedWrapper : public BaseWrapper". (Zur Erklärung: Wenn du nichts anderes angibst, setzt C++ eine private Ableitung ein, die polymorphend Typumwandlungen funktionieren aber nur entlang öffentlicher Vererbungslinien)
-
phlox81 schrieb:
Also so ganz kannst du die STL Container nicht unter einen Hut bringen, denn sie sind alle leicht unterschiedlich
ja, thx, ich weiß, aber ich brauche auch nicht _alle_ eigenschaften von _jedem_ container, sondern im grunde nur die begin() und die end() funktionen bei den nicht-assoziativen containern. (also nicht <map> oder sowas, sondern nur <list> <vector> <queue> <stack> <deque>... + mein eigener array-ähnlicher container, den ich da schreiben will)
Wie ich das allgemein mit all den iteratoren noch hinkriege, werde ich sehen...CStoll schrieb:
: public BaseWrapper
okay, danke schön, jetzt klappts wunderbar!

im grunde echt n dummer tippfehler von mir... wird sich nicht wiederholen! :p