PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Beziehungen zwischen zwei C++ KLassen impl.



jancarsten
23-10-2005, 18:33
HI!

Ich habe folgendes Problem. Ein Klasse A steht mit einer Klasse B in einer 1:1 oder 1:n oder n:m in Beziehung. Wie Programmiert man solch eine Beziehung in C++? Im Netz finde ich immer nur Erklärungen(UML) aber nie ein konkretes Beispiel wie man sowas Programmiert. Kann mir das mal jemand schnell erklären mit Hilfe von C++ Code? Wenn es geht mit einer dyn. Liste.


mfg
Jan

anda_skoa
23-10-2005, 22:05
Zum Beispiel 1:n


class A
{
public:
A() {}
};

class B
{
public:
B() {}

void addA(A* a) { m_listOfAPointers.push_back(a); }

private:
list<A*> m_listOfAPointers;
};


Falls du ein konkretes Problem hast, kann man vielleicht ein besseres Beispiel finden.

Ciao,
_

jancarsten
24-10-2005, 18:29
HI!

Danke schonmal. So jetzt habe ich in der liste zum Bsp. 5 Objekte gespeichert. Wie kann ich mir jetzt zum Bsp. das 2 Objekt raus hollen und löschen oder dieses Objekt weiterverarbeiten?

Noch ne Fragen. Die klasse A hat jetzt noch get/set Methoden (für den Namen) wie kann ich zum Bsp. eine get Methode aufrufen und mir zum Beispiel einen Namen ausgeben lassen?

anda_skoa
24-10-2005, 19:22
Bei einer list<> mit Iteratoren.

zB


// setName auf allen Elementen der Liste aufrufen
for (list<A*>::iterator it = m_listOfAPointers.begin(); it != m_listOfAPointers.end(); ++it)
{
(*it)->setName("foo");
}


http://www.cppreference.com/cpplist/

Mit einem vector statt einer list kann man auch direkt auf Element zugreifen, so wie bei einem Array.

Ciao,
_

jancarsten
24-10-2005, 20:04
HI!

So eine allerletzte frage ;). Also ich suche jetzt in einem Vector nach einem Object mit der ID XYZ die ich über eine set Methode angegeben habe. Wenn ich jetzt dieses Objekt gefunden habe wie lösche ich dieses?

mfg Janosch

anda_skoa
24-10-2005, 20:52
// Annahme: vector<A*> m_vector;

for (vector<A*>::iterator it = m_vector.begin(); it != m_vector.end(); ++it)
{
A* a = *it;
if (a->id() == "foo")
{
m_vector.erase(it);
delete a; // nur wenn man das Objekt auch löschen will
break;
}
}


Ciao,
_

jancarsten
01-11-2005, 18:38
HI!

Ich nochmal :eek:

Eine kleine Frage habe ich noch ;).

Also in meinem Programm (siehe unten) lege ich ein Vector an. Diesen Vector fülle ich dann mit Stringwerte und gebe die Adressen dieser Stringwerte wieder aus. So wenn ich jetzt aber zur Laufzeit einen neuen Stringwert in den Vector Schreiben ändern sich anschlissend die ganzen Adressen. Das ist ziemlich blöde, weil in meinem richtigen Programm kopiere ich ja die aktuelle Adresse(von vector A) der Objekte in ein weiteres Objekt(B) und bei erneutem Aufruf des Objektes(B) (nach hinzufügen von daten in vector A) kommt natürlich nur mist dabei raus. Wie kann ich jetzt sicherstellen, dass sich die Adressen nicht ändern. Brauche ich dazu ein "Temp" vector in dem ich die alten Adressen zwischen speichere oder kann man das eleganter lösen? Wenn ja wie? Gibt es in C++ dafür spezielle lösungen?

Ich habe mal ein kleines Testprogramm geschrieben damit man meine frage besser versteht. Hier ist das Programm:



#include <vector>
#include <list>
#include <string>
#include <vector>
#include <iostream>

using namespace std;

int main(){

string eingabe;

vector<string> test;

test.push_back("Test1");
test.push_back("Test2");
test.push_back("Test3");
test.push_back("Test4");
test.push_back("Test5");
test.push_back("Test6");

for(unsigned int i = 0 ; i < test.size() ; i++){

cout << "Vector inhalt: " << &test[i] << endl;

}

cout << "Geben Sie einen neuen String an: ";
cin >> eingabe;

test.push_back(eingabe);

for(unsigned int i = 0 ; i < test.size() ; i++){

cout << "Vector inhalt: " << &test[i] << endl;

}

getchar();
getchar();
return 0;
}

locus vivendi
01-11-2005, 20:00
Wenn du von vornherein weisst, wieviele Objekte es werden, kannst du genügend Speicher mit der reserve-Funktion des Vektors reservieren. Möglicherweise wäre es besser, das Programm so zu gestalten, dass die Reallokation des Vektors berücksichtigt wird, und nicht zu Fehlern führt.

jancarsten
01-11-2005, 20:15
...... dass die Reallokation des Vektors berücksichtigt wird,

hmmm nur weiß ich nicht wie das gehen soll ;)

locus vivendi
01-11-2005, 20:33
hmmm nur weiß ich nicht wie das gehen soll
Da kann man keine Blanko-Antwort geben; Das kommt auf den Rest deines Programms an. Etwas was zum Bleistift fast immer geht, ist, dass du nur einen Zeiger auf den Vektor selber speicherst, und den Index des gesuchten Elements. Der Index bleibt ja gleich. Etwas was nur manchmal gut geht, wäre, eine "Observer"-Implementierung zu haben, indem der Vektor (geeignet gewrapped) andere Objekte benachrichtigt, wenn sich sein Zustand ändert. Die anderen Objekte könnten dann ihre Verweise anpassen. Aber man muss ja auch nicht immer einen Vektor nehmen. Vielleicht passt ja auch ganz einfach eine Liste (speziell halt std::list). Dann tritt dein jetziges Problem gar nicht erst auf.

Falls du Lust hast, würde ich empfehlen, eine strukturierte Einführung in C++ zu lesen, z. b. "den" Stroustrup.

jancarsten
01-11-2005, 22:20
hmmm und wie geht das mit der liste?

jancarsten
01-11-2005, 22:50
HI!

Habe das Problem mit einer Liste hinbekommen. THX für eure hilfe :D

mfg janosch

anda_skoa
02-11-2005, 14:22
Das ist auch mit einer Liste nicht sehr schön.

Bei einem Container sollte man keine Annahmen über seine Implementation treffen, die nicht durch den Standard als Verhalten vorgegeben werden.

Wozu brauchst du die Adressen der Elemente überhaupt?

Ciao,
_

locus vivendi
02-11-2005, 16:25
Bei einem Container sollte man keine Annahmen über seine Implementation treffen, die nicht durch den Standard als Verhalten vorgegeben werden.
Deshalb hatte ich ja die Liste vorgeschlagen. Bei der std::list bleiben ja Verweise gültig. Allerdings hätte ich vielleicht deutlicher sagen sollen, dass das nicht notwendigerweise für andere Listen als die std::list gilt. Aber letzendlich ist es sowieso müßig, eine Empfehlung zu geben, wenn man nicht genau weiß, was gebraucht wird.