C++ Container für verschiedene Objekte

Hallo zusammen,

die STL biete ja einige Container an, in den man aber nur jeweils einen bestimmten Typ speicher kann. Ich brauche aber eine Möglichkeit verschiedene Objekte von Klassen zu speichern, die von einer Klasse abgeleitet sind z.B. :

Code:
#include <iostream>
#include <vector>

using namespace std;

class Mitarbeiter
{
	public:
		Mitarbeiter( char *name, int ID)
		:name(name),
		 id(ID)
		{}
		int getID(void)
		{
			return id;
		}
		char *getName(void)
		{
			return name;
		}
	private:
		char *name;
		int id;
};

class Manager : public Mitarbeiter
{
	public:
		Manager(int gehalt, char *name, int ID)
		:Mitarbeiter(name,ID),
		 gehalt(gehalt)
		 {}
		 int getGehalt(void)
		 {
			 return gehalt;
		 }
	private:
		int gehalt;
};

class Abteilungsleiter : public Mitarbeiter
{
	public:
		Abteilungsleiter(int gehalt, char *name, int ID, char *abteilung)
		:Mitarbeiter(name,ID),
		abteilung(abteilung),
		gehalt(gehalt)
		{}
		char *getAbteilung(void)
		{
			return abteilung;
		}
		int getGehalt(void)
		{
			return gehalt;
		}
	private:
		char *abteilung;
		int   gehalt;
};

typedef vector<Mitarbeiter> firmen_db;

int main(void)
{
	firmen_db musterFirma;
	Manager klaus(2000,"Klaus Mustermann",1);
	Abteilungsleiter manny(1000,"Manny Mustermann",2,"Verkauf");
	cout<<klaus.getName( )<<" "<<klaus.getID( )<<" "<<klaus.getGehalt( )<<endl;
	cout<<manny.getName( )<<" "<<manny.getID( )<<" "<<manny.getGehalt( )<<manny.getAbteilung( )<<endl;
	
	musterFirma.push_back(klaus);
	musterFirma.push_back(manny);
	
	//Manager &test = dynamic_cast<Manager&>(musterFirma.at(0));
	
	return 0;
}

In einen Vector will ich nun Manager oder Abteilungsleiter speichern, jedoch nimmt der Vector Mitarbeiter auf, also die Basisklasse somit gehen die Methoden/Variablen der abgeleiteten Klassen verloren ?!

Hat einer mal einen Vorschlag, wie man sowas lösen könnte ?

THX
 
typedef vector<Mitarbeiter*> firmen_db;

Und in der main() dann die einzelnen Objekte reinpacken:

firmen_db musterFirma;
firmen_db::iterator it, end;
musterFirma.push_back(new Manager(2000,"Klaus Mustermann",1));
musterFirma.push_back(new Abteilungsleiter(1000,"Manny Mustermann",2,"Verkauf"));

Wichtig ist das du am Ende den Speicher wieder freigibst.

end=musterFirma.end();
for(it=musterFirma.begin(); it!=end; ++it)
delete *it;

Durch den Zeiger auf die Basisklasse nutzt du Polymorphie, und kannst über diesen Zeiger auch auf die Memberfunktionen abgeleiteter Klassen zugreifen.

(Deine Programm hat noch einige Schwächen aber hab grade leider keine Zeit... gucks mir später nochmal an :)
 
Danke erstmal, ich probier es gleich mal aus !

(Deine Programm hat noch einige Schwächen aber hab grade leider keine Zeit... gucks mir später nochmal an smile

Ich weiß, Default Contructor fehlt, Zuweisung usw. Es war nur mal so hingeknallt !
 
Also ich habs mir jetzt auch nicht genau angeschaut, allerdings finde ich deine Vererbungshierachie nicht gerade ideal. Mal als Beispiel: Jeder Mitarbeiter hat doch normalerweise ein Gehalt oder nicht? Deshalb gehört das z.B. auch oben in die Basisklasse rein.

Erstens solltest du deine Methoden virtuell deklarieren, und die konkreten Unterklassen-Objekte dann so in deinen vector packen wie cr das vorgeschlagen hat. Stichwort: Polymorphie.

Ansonsten wenn du halt eine Methode hast die sehr spezifisch ist, und nur in einer speziellen Unterklasse vorhanden ist, du diese aber unbedingt irgendwie aufrufen willst, so kannst du RTTI benutzen. D.h. du kannst testen ob ein Mitarbeiter-Objekt in deinem Array z.B. vom Typ Abteiliungsleiter ist, und wenn ja, dieses Objekt dann auf Abteilungsleiter casten, und dort dann deine spezielle Methode aufrufen.
 
Hi,

das Beispiel mit den Mitarbeitern war nur so hingeknallt und hat mit dem eigentlichen Programm nix zu tun, war nur zur demonstration des Problems.
 
Naja also wie gesagt, wenn du verschiedene Objekte da rein tun willst, welche alle diesselbe Oberklasse haben, dann kannst du das 1.) unter Ausnutzung der Polymorphie tun und 2.) falls es spezielle konkrete Objekte gibt, welche Methoden haben die von der Basisklasse abweichen, mittels RTTI dann trotzdem diese Methoden benutzen.

Falls du einfach nen Container willst in den du *alles* mögliche reinpacken willst, also unabhängig von Klassenhierachien, dann bleibt dir wohl nix anders übrig als z.B. nen vector aus void Pointern zu deklarieren.
Beispiel:
Code:
vector<void*> test;
int    n = 5;
char c = 'A';
CString str = _T("Test");

test.push_back(&a);
test.push_back(&n);
test.push_back(&str);

//Den CString wieder auslesen:
CString* myStr = (CString*)test[2];

//Jetzt irgendwas damit machen...

Nicht sehr elegant, aber anders gehts meines Wissens nicht. Man kann da bestimmt aiuch noch einiges mit Templates tricksen, wenn die Objekte die man da reinpacken will in irgendner Beziehung stehen, aber das ist wieder ne Geschichte für sich...
 
Zurück
Oben