Datencontainer
-
Infotyp schrieb:
"." verwendest du auch bei Objekten, die du auf dem Stack anlegst....
Infotyp schrieb:
ups...
und "->" bei struct auf dem Heap
..Ähhh ... das ist irgendwie "richtig gemeint", aber trotzdem nicht richtig.
Viel einfacher:
- "." bei Objekt(referenz)en
- "->" bei Pointern
Kleines Beispiel, warum die "Stack/Heap"-erklärung nicht greift:
void callByVal(string s) { cout << s.length(); } void callByRef(string& s) { cout << s.length(); } void callByPtr(string* s) { cout << s->length(); } int main() { string stackStr; string *heapStr = new string; callbyVal(stackStr); callbyRef(stackStr); callbyPtr(&stackStr); callbyVal(*heapStr); callbyRef(*heapStr); callbyPtr(heapStr); delete heapStr; return 0; }
BTW: IMO ist "->" ein überflüssiges syntaktisches Konstrukt (C-Altlast; der Compiler setzt das sowieso kontextbezogen um) .. was man ja offensichtlich bei Referenzen schon begriffen hat.

Gruß,
Simon2.
-
Simon2 schrieb:
BTW: IMO ist "->" ein überflüssiges syntaktisches Konstrukt (C-Altlast; der Compiler setzt das sowieso kontextbezogen um) .. was man ja offensichtlich bei Referenzen schon begriffen hat.

Altlast vielleicht, aber nicht überflüssig - schließlich ist es immer wieder notwendig, mit Pointern umzugehen - und
p->xsieht eleganter aus als(*p).x. Und außerdem kannst du op-> auch überladen (z.B. für Smart-Pointer).
-
CStoll schrieb:
...
p->xsieht eleganter aus als(*p).x...Stimmt schon, aber warum nicht einfach
p.x, wie bei Referenzen auch ?
Ein nicht geringes Problem entsteht ja semantisch (z.B. bei operator-overloading) durch die Äquivalenz von "*." und "->" ... vom "Klammerwirrwarr" und den damit verbundenen Fehlern bei komplexeren Konstrukten noch gar nicht gesprochen ...Gruß,
Simon2.
-
Wie kann ich etwas aus dem struct löschen? Ich wollte ein Liniensegment, hier Linie1 löschen
#include <iostream> #include <vector> #include <string> using namespace std; struct TPunkt { double x; double y; TPunkt(const double _x, const double _y) { x = _x; y = _y; } }; struct TLinienSegment { vector<TPunkt> Punkte; string label; }; vector<TLinienSegment> Liniensegmente; int main() { //... //Liniensegmente füllen, meinetwegen so: TPunkt p1(100,100); TPunkt p2(200,100); TLinienSegment Liniea; Liniea.Punkte.push_back(p1); Liniea.Punkte.push_back(p2); Liniea.label = "meine Linie"; TLinienSegment Linie1; Linie1.Punkte.push_back(p1); Linie1.Punkte.push_back(p2); Linie1.label = "Linie1"; Liniensegmente.push_back(liniea); Liniensegmente.push_back(liniea); //remove Linienelement; delete [] Liniensegmente.linie1; Liniensegmente.linie1; = NULL; //Fehler return 0; }vielen Dank für Hilfe..
-
delete ist hier falsch. Zum löschen von Elementen aus einem vector kann man erase() verwenden. Wenn das Element am Ende des vectors ist auch pop_back(). Bei erase mußt du wissen, an welcher Position im vector sich dein element befindet;
Bsp.Liniensegmente.push_back(liniea); Liniensegmente.push_back(liniea); // nun sind zwei TLinienSegment Objekte im vector // löschen des ersten Liniensegmente.erase(Liniensegmente.begin()); // löschen des letzten Liniensegmente.pop_back();
-
sorry bin Anfänger..
erase habe ich ausprobiert, ich kann aber nicht auf das i-te Element einer for-Schleife zugreifen.for (i = 0; i<v1.size(); i++) { startIterator = v1.begin(); anzahl =0; for(int k=0;k<v1.size()&&anzahl<2;k++) { if(strcmp (v1[i]->mainIdent, v1[k]->mainIdent) == 0)++anzahl; } if (anzahl > 1 ) { v1.erase( startIterator +i ); //hier wird der falsche gelöscht // v1[i]->mainIdent[0] = 0; Ist der richtige, ist aber nicht gelöscht
-
<---> schrieb:
sorry bin Anfänger..
erase habe ich ausprobiert, ich kann aber nicht auf das i-te Element einer for-Schleife zugreifen.sicher geht das.
<---> schrieb:
for (i = 0; i<v1.size(); i++) { startIterator = v1.begin(); anzahl =0; for(int k=0;k<v1.size()&&anzahl<2;k++) { if(strcmp (v1[i]->mainIdent, v1[k]->mainIdent) == 0)++anzahl; } if (anzahl > 1 ) { v1.erase( startIterator +i ); //hier wird der falsche gelöscht // v1[i]->mainIdent[0] = 0; Ist der richtige, ist aber nicht gelöscht.. nun Du löscht das i'te Element in 'vl'. D.h. nach dem Löschen ist das Element nicht mehr vorhanden.
Was soll das Programm eigentlich tun? Wenn der Algorithmus dafür sorgen soll, dass da keine Kopien mehr in 'vl' vorkommen, so kannst Du den stl-algorithmus unique benutzen.
Im Prinzip so:std::sort( vl.begin(), vl.end() ); vl.erase( std::unique( vl.begin(). vl.end() ), vl.end() );Du benötigst aber noch einen Vergleichsoperator für den Element-Typ in 'vl'.
Gruß
Werner
-
Das Programm soll unter einer bestimmten Bedingung Elemente aus dem Vektor löschen. Da ich sicherstellen möchte, dass jedes Element mind 1 x vorkommt, steht in der if Anweisung anzahl >1. Vermutlich mache ich einen Fehler beim Zugriff auf das zu löschende Element. Denke der Iterator stimmt nicht, ich finde aber nicht wo. Wenn du es findest ist super, aber denke es ist schwierig zu finden, ohne zu debuggen. Meine Frage daher, bin ich auf dem richtigen Weg oder ist der Ansatz grundsätzlich falsch? Denn der Vector ist ja mit einer Struktur gefüllt.
Und wenn ich nicht lösche, sondern das betreffende Element der Struktur auf 0 setze, wird das richtige ausgegeben. s.u. v1[i]->mainIdent[0] = 0;
Von daher, kann man ein Vektorelement, das auf eine Struktur oder Klasse verweist überhaupt löschen?
Vielen Dank für Antwort!!!
for (i = 0; i<v1.size(); i++) { startIterator = v1.begin(); anzahl =0; for(int k=0;k<v1.size()&&anzahl<2;k++) { if(strcmp (v1[i]->mainIdent, v1[k]->mainIdent) == 0)++anzahl; } if ( bedingung && anzahl > 1 ) { v1.erase( startIterator +i ); //hier wird der falsche gelöscht // v1[i]->mainIdent[0] = 0; löscht den Richtigen
-
<---> schrieb:
Das Programm soll unter einer bestimmten Bedingung Elemente aus dem Vektor löschen. Da ich sicherstellen möchte, dass jedes Element mind 1 x vorkommt, steht in der if Anweisung anzahl >1.
Du meinst 'höchstens einmal' - oder?
<---> schrieb:
Vermutlich mache ich einen Fehler beim Zugriff auf das zu löschende Element.
Nein, ich glaube nicht, das Problem liegt woanders.
<---> schrieb:
Denke der Iterator stimmt nicht, ich finde aber nicht wo. Wenn du es findest ist super, aber denke es ist schwierig zu finden, ohne zu debuggen. Meine Frage daher, bin ich auf dem richtigen Weg oder ist der Ansatz grundsätzlich falsch? Denn der Vector ist ja mit einer Struktur gefüllt.
Der vector ist mit mehreren Elementen einer Struktur gefüllt.
<---> schrieb:
Und wenn ich nicht lösche, sondern das betreffende Element der Struktur auf 0 setze, wird das richtige ausgegeben. s.u. v1[i]->mainIdent[0] = 0;
Wenn ein Element im vector gelöscht worden ist, so existiert es nicht mehr. Es kann also auch nicht mehr ausgegeben werden; auch nicht mit einer '0'.
<---> schrieb:
Von daher, kann man ein Vektorelement, das auf eine Struktur oder Klasse verweist überhaupt löschen?
Ich verstehe nicht was Du mit dieser Frage meinst. Ein Vektorelement verweist auf keine Struktur.
<---> schrieb:
v1.erase( startIterator +i ); //hier wird der falsche gelöscht // v1[i]->mainIdent[0] = 0; löscht den Richtigenkorrekt wäre hier, den Index 'i' zu dekrementieren, da er bereits auf das nächste Element verweist. Alle Elemente, die hinter dem gelöschten stehen, sind nach dem Löschen um einen Index nach vorne gerutscht.
Wie gibst Du den Vektor anschließend aus und wie viele Elemente besitzt er noch?
Gruß
Werner
-
Oh, da habe ich mich anscheinend unklar ausgedrückt.
Ich möchte sicherstellen, dass nach dem Löschen von jedem Elementtyp noch eins da ist. Es muss also A, B, C mind 1 x vorhanden sein.
z.B.
v1[i]->mainIdent: A
nächstes v1[i+1]->mainIdent: B
v1[i+1]->mainIdent: B
v1[i+1]->mainIdent: C
v1[i+1]->mainIdent: B
v1[i+1]->mainIdent: B
v1[i+1]->mainIdent: A
v1[i+1]->mainIdent: CDa ich das Löschen nicht hinbekommen habe, habe ich v1[i]->mainIdent[0] = 0; So konnte ich testen, was raus soll und welche angezeigt werden müssen. Das funktioniert auch richtig. Daher möchte ich das auf 0 setzen durch "tatsächliches" Löschen erseten.
Mit Stuktur meine ich, dass v1[i+1]->mainIdent, entsprechend wie TLinienSegment Liniea;
Liniea.Punkte.push_back(p1);
aufgebaut ist.vector<TLinienSegment> Liniensegmente entspricht v1
TLinienSegment Liniea;
Liniea.label = "A"; Liniea.label entspricht mainIdentIch hoffe, es ist nachvollziehbar
nochmals vielen Dank!