ableitung einer vektor-klasse
-
hallo forum,
lässt sich eine vektor-klasse vererben?
etwa so:#include <vector> class AbgeleiteteKlasse : public std::vector<IrgendeineKlasse> { // Irgendwelche Definitionen };Das dies vom Compiler ohne weiteres hingenommen wird habe ich schon getestet.
Aber: gibt es mit irgendwelchen delikaten funktionen des vector-templates vielleicht ein problem mit rückgabewerten oder sowas?
Und lassen sich die <algorithm>-Templates auch auf eine Ableitung von vector<> anwenden?
-
Du solltest einfach berücksichtigen, dass die Standardcontainer nicht für Vererbung konzipiert sind. Beispielsweise sind sie nicht polymorph.
Je nach Anwendungsfall ist es vielleicht ratsamer, einen
std::vectorzu wrappen. Was willst du denn genau anstd::vectorerweitern?
-
was meinst du mit wrappen?
AbgeleiteteKlasse soll eine Liste von IrgendeineKlasse sein, die zusätzliche funktionen (zum beispiel suchfunktionen) für IrgendeineKlasse enthält.
Also im Proinzip soll es eine Kapselklasse für eine Liste sein
-
Eben, dann ist ein Wrapper/Adapter/Kapselklasse eher das Richtige.
class Kapsler // vielleicht einen besseren Namen wählen ;) { private: std::vector<IrgendeineKlasse> MyVector; public: // deine Schnittstelle };Das hat den Vorteil, dass du nicht alle Operationen auf einem
std::vectorerlauben musst, sondern dich auf die beschränken kannst, die du für nötig hältst (z.B. Einfügen, Suchen, Löschen).
-
std::vector hat keinen virtuellen Destuktor und ist alleine schon deswegen für Vererbung (und die damit häufige Polymorphie) ungeeignet.
Im übrigen wird zusätzliche Funktionalität besser als freie Funktion und als Template Funktion implementiert, da diese dann auch von anderen Containern benutzt werden kann (sofern die Bedingungen erfüllt sind).
-
drakon schrieb:
std::vector hat keinen virtuellen Destuktor und ist alleine schon deswegen für Vererbung (und die damit häufige Polymorphie) ungeeignet.
Kein virtueller Dtor heißt nicht dass es für Vererbung allgemein ungeeiget ist, sondern nur dass es nicht polymorph behandelt werden darf.
Allerdings üwrde ich auch eher einen wrapper bauen, wenn überhaupt. Die zusätzlichen Funktionen (z.B. die angesprochene Suchfunktion) können oft sehr gut auch mit einem normalen vector und <algorithm> und einer Handvoll Funktoren etc. erledigt werden.
-
na gut

dann also wieder eine wrapper-klasse schreiben
danke
-
pumuckl schrieb:
drakon schrieb:
std::vector hat keinen virtuellen Destuktor und ist alleine schon deswegen für Vererbung (und die damit häufige Polymorphie) ungeeignet.
Kein virtueller Dtor heißt nicht dass es für Vererbung allgemein ungeeiget ist, sondern nur dass es nicht polymorph behandelt werden darf.
Darum habe ich das in Klammern noch geschrieben. Ist vielleicht ein wenig ungeschickt formuliert, aber ich meinte damit, dass wenn Vererbung getrieben wird oftmals Polymorphie erreicht werden will und es für das ungeeignet ist.
-
drakon schrieb:
Darum habe ich das in Klammern noch geschrieben. Ist vielleicht ein wenig ungeschickt formuliert, aber ich meinte damit, dass wenn Vererbung getrieben wird oftmals Polymorphie erreicht werden will und es für das ungeeignet ist.
Wobei ich hier bezweifle, dass man einen
MyVectorpolymorph alsstd::vectoransprechen will.Aber mit einem Wrapper ist man grundsätzlich flexibler, vor allem, wenn man Funktionalität einschränken will. Ansonsten, falls nur wenige zusätzliche Operationen benötigt werden, stellen wie gesagt auch freie Funktionen (zum Beispiel im STL-Algorithmen-Stil) eine Möglichkeit dar.
-
ist das hier korrekter programmierstil?
oder würdet ihr das anders machen?#include <vector> class IrgendeineKlasse { // ... }; typedef vector<IrgendeineKlasse> List; class Wrapper { private: List l; public: List& List() {return l;} // ... };mit List() wird direkter zugriff auf ALLE funktionen der vector-klasse ermöglicht, da die klasse den vektor nur erweitern und nicht beschränken soll.
-
Mal abgesehen davon, dass ich das typedef in der Klasse machen würde, (wegen dem späteren Zugriff auf den Typen vlt.) ist das Problem so ja, dass du überhaupt keine Kapselung der Funktionalität hast. Sprich wenn du jetzt bei push_back etwas eigenes haben willst, kann der Benutzer immernoch über das von dir zurückgegeben Objekt die ursprüngliche Funktion aufrufen. Das hättest du nicht, wenn du eine richtig ableitbares Objekt hast, dass virtuelle Funktionen anbietet, welche du überschreiben kannst. Oder wie man es hier eher machen würde das Obejkt nicht freigeben und dann über selbst geschriebe Funktionen die Funktionen des Objektes kapseln.
class myList { public: void push_back ( whatever el ) { if ( el == irgendwas) l.push_back ( el ); } ... private: std::vector<whatever> l; };So in etwa. Aber das ist halt sehr viel Arbeit, wenn du die gesamte Funktionalität haben willst.
Aber wie schon gesagt, wenn du rein neue Funktionalität zufügen willst, ist eine ableitung, oder eine solche Klasse gar nicht nötig, sondern lediglich eine freie Funktion, die das für dich macht. Das gute daran ist, dass du (je nach Anforderung) dann gleich eine Funktion hast, die mit anderen Containern auch funktioniert, ohne eine Zeile Code schreiben zu müssen.