frage zu template/vector/Typerkennung
-
hallo!
folgendes problem existiert:
habe eine klasse ASN1AbstractCollection:
template<class T> class ASN1AbstractCollection : public vector<T>, public ASN1Typedazu noch eine Klasse ASN1Sequence, die von <code>ASN1AbstractCollection</code> abgeleitet ist; mittels asnsequence->push_back(primitive_type) werden objekte angefügt. parallel dazu existieren Typen wie ASN1Integer, die nur von ASN1Type
abgeleitet sind;nun habe ich eine Funktion
void writeType(ASN1Type *t) { t->encode(this); }die abhängig vom übergebenen Typpointer die jeweils ausimplementierte encode-Funktion aufruft.
die problemstellung findet man unter der zeile "Funktioniert NICHT"
ofstream *os; int val1 = 3; int val2 = 4; int seq_size = 0; ASN1Integer *asn_int1 = new ASN1Integer(val1); ASN1Integer *asn_int2 = new ASN1Integer(val2); ASN1Sequence *asn_seq = new ASN1Sequence(seq_size); asn_seq->push_back(*asn_int1); asn_seq->push_back(*asn_int2); DEREncoder *enc = new DEREncoder(os); //das funktioniert enc->writeType(asn_int1); //das funktioniert enc->writeType(asn_seq); //das funktioniert NICHT enc->writeType(&asn_seq->at(0));nun wird nicht wie bei den anderen zwei writeType-Funktionen die jeweilige encode-funktion aufgerufen, sondern die (nicht implementierte) von ASN1-Type, er dürfte also den typ nicht kennen...
any comments?
mfg
-
Kurze Zwischenfrage:
Ist
&asn_seq->at(0)identisch mit
&(asn_seq->at(0))?
-
ändert nichts am ergebnis.
nochwas zum besseren verständnis:
ASN1Sequence ist im prinzip ein vector der mit ASN1Types gefüllt ist;
dazu ist ASN1Sequence selber noch ASN1Type!
-
Schon klar du hast einen Baum bestehend aus Knoten von unterschiedlichen Typen, die aber eine gemeinsame Schnittstelle besitzen.
Kann es sein, dass du eine Klasse mehrfach von ASN1Type abgeleitet hast?
-
ERRATA zum vorigen:
FRAGE:
ist&asn_seq->at(0)das gleiche
&(asn_seq->at(0))das ist NICHT das selbe:
beim ersten sollte er die encode-funktion des in der sequence gespeicherten typs nutzen, tut er aber nichtbeim zweiten zeigt er wieder auf die ASN1Sequence!
@ableitung:
naja, jedenfalls entspricht eine Sequenz einer ASN1AbstractCollection<ASN1Type >, mehrfache ableitungen sind jetzt aber nirgendwo festzustellen
-
Na dann ist es doch klar. Wenn, dann müsstest Du ASNType1 Pointer speichern, da dir sonst so der konkrete Typ verloren geht.
Du weißt, dass std::vector nicht zum (öffentlichen) Ableiten gedacht ist?
-
in der tat, guter tip:)
das mit dem öffentlichen ableiten wusste ich nicht, private/protected ist lieber gesehen? im öffentlichen fall sollte ich mir dann ne vec_class selber schreiben oder welches konzept wird dann angewendet?
-
Mach eine private ableitung und gib dann sozusagen die vector-Methoden "frei" die du öffentlich machen willst, etwa so:
class X : private std::vector<bla> { public: using push_back; };Ehm, ich hoffe es ist syntaktisch so korrekt.

-
Öffentlich ableiten suggeriert (oder strenger gesehen: impliziert) Polymorphie. Da std::vector aber keinen virtuellen Destruktor hat, kann er das niemals garantieren. Ich glaube, es gibt nur sehr wenige Klassen in der STL, die sich zur Vererbung eignen und dafür vorgesehen sind.
Und mal ehrlich... im Prinzip ist es doch nur Faulheit, weil man nicht die Schnittstellen vom Vektor wiederholen möchte, wenn man ihn als Member hält
Du musst nicht öffentlich von vector erben, weil Du garkein vector bist, sondern einen vector hast. Private-Ableitung wäre nur zu rechtfertigen, wenn Du auf protected Member zugreifen willst - wozu es aber garkeine Notwendigkeit gibt.Außerdem - willst Du wirklich die gesamte vector-Schnittstelle zur Verfügung stellen? Ich wäre mir nicht sicher, ob das so wirklich sinnvoll ist.
-
@inner_fire
Bei der zweiten Variante von mir ist definitiv die Adresse des Objekts gemeint, die die Funktion at () zurückliefert.Aber mir fällt an dieser Stelle etwas anderes auf...
ASN1Integer *asn_int2 = new ASN1Integer(val2); asn_seq->push_back(*asn_int2);Darf ich diese Zeile dahingehend interpretieren, dass du im Vektor direkt die Objekte hälst und nicht Zeiger auf die Objekte?
Dies würde erklären warum die falsche Funktion aufgerufen wird, weil bei push_back () das uebergebene Objekt in ein Objekt der Oberklasse kopiert würde. (Mit der Konsequenz, dass dann natürlich auch immer die Funktion der Oberklasse aufgerufen wird, wenn du auf die im Vektor abgelegten Objekte zugreifst.)
-
Irgendwo hatte ich mal gelesen, das man nicht von den Containern der STL ableiten soll...
Und für eine Hat ein Beziehung, sollte man das auch bitte vermeiden.
Wenn du nicht alle schnittstellen zur verfügung stellen willst,
kannst du ja Methoden zur Verfügung stellen, die entsprechen const_iteratoren zurück geben.
-
Stimmt das Ableiten von einer STL-Klasse ist kritisch, da die Funktionen der STL-Klasse nicht virtuell sind, dies hat allerdings mit dem Problem von inner_fire soweit ich das beurteilen kann nichts zutun, da dieser seine abgeleitete Klasse gar nicht über die Schnittstelle des STL-Vectors anspricht.
-
danke für deine mühe; 7H3 N4C3R hat dies auch mitgeteilt und ich habs schon entsprechend geändert.
@all:
werde das jetzt entsprechend auf private umarbeiten, mit den notwendigen zugriffsfunktionen;
allerdings habe ich schon öfter gesehen dass von stl abgeleitet wird, waren ws alles faule säckethx