Collection Class

kerian

Erfahrenes Mitglied
Hallo,
arbeite mit MFC VC 6.0.
Jetzt zum meinem Problem. Wenn ich die COblist Classe zum speichern von Objecten nehme geht das speichern und das lesen einwandfrei, aber mein Problem ist das auslesen!
Ich weiss nie was für ein Objekt sich hinter einr pos befindet. Kann man das anders lösen?

Code:
COblist list;
Ctest1 *ptest1 = new Ctest1();
Ctest2 *ptest2 = new Ctest2();
Ctest3 *ptest3 = new Ctest3();

list.AddTail(ptest1);
list.AddTail(ptest2);
list.AddTail(ptest3);

for(int i=0;i<3;i++)
{ 
if()ptest1 = (Ctest1*)list.GetAt(pos);
if()ptest2 = (Ctest2*)list.GetAt(pos);
List.GetNext( pos );
}

Wenn ich jetzt auslese weiss ich nicht was sich hinter der pos befindet? Kann man das irgendwie rausfinden?
 
Also ich machs immer so:
Code:
int i =0;
pos = pListe->GetHeadPosition();
while (pos!=NULL)		//Liste durchlaufen
{
CMyElement *pElement = (CMyElement*) pListe->GetNext(pos);
...
i++;
}
Ist aber auch nicht sonderlich elegant. Wenn's noch bessere Lösungen gibt immer raus damit ;)
 
Das sieht gut aus! Aber mein Prob ist, dass das nicht immer diesselbe Classe ist!
Also micht immer CMyElement sondern auch vielleicht CMyAuto oser CMyCat. Die sich hinter einer pos befindet!
 
Sorry da war ich wohl etwas zu schnell! :-(
In C++ gibt es meines Wissens keine Funktion um ein richtigen Cast sicherzustellen.
Mir würde nur ne Klasse in einer Klasse einfallen. In der ersten müsstest du dann vermerken welcher Klassentyp die Klasse enthält.
Code:
CMyContainer
{
int Typ;                //1-MyCar, 2-MyCat
CObject *pElement;
}
]
 
Also du schreibst eine Klasse die 2 Memervariablen hat.
1. Membervariable vom Typ CObject*
2. Membervariable vom (z.B.) Typ int. In dieser speicherst du so zusagen die Art der Klasse die du in der 1. Memberrvariable speicherst. Dein Code würde ca. so aussehen
Code:
COblist list;
Ctest1 *ptest1 = new Ctest1();
CMyContainer pContainer1 = new CMyContainer;
pContainer1->myclass = (CObject*)ptest1;
pContainer1->art = 1;
Ctest2 *ptest2 = new Ctest2();
CMyContainer pContainer2 = new CMyContainer;
pContainer2->myclass = (CObject*)ptest2;
pContainer2->art = 2;
...
list.AddTail(pContainer1);
list.AddTail(pContainer2);
...

pos =list.GetHeadPosition();
while (pos!=NULL)		//Liste durchlaufen
{
CMyContainer *pContainer = (CMyContainer*) List.GetNext(pos);
if(pContainer->art==1)

...

}
Auf eine bessere Kapselung solltest du natürlich achten ;)
 
Zuletzt bearbeitet:
Anstatt eine Containerklasse zu verwenden, könnte man die vorhandenen Klassen (vorausgesetzt, sie sind irgendwie von CObject abgeleitet ) mit den Makros DECLARE_DYNAMIC und IMPLEMENT_DYNAMIC so erweitern, dass zur Laufzeit die Klasse der Objekte bestimmt werden kann:

Code:
///////////////////////////////////////////////
// CTest Deklaration

class CTest : public CObject
{
public:
    DECLARE_DYNAMIC(CTest)

    CTest();
    ~CTest();
};

///////////////////////////////////////////////
// CTest Implementation

IMPLEMENT_DYNAMIC(CTest, CObject)

CTest::CTest()
{
}

CTest::~CTest()
{
}

///////////////////////////////////////////////
// Verwendung

COblist list;
CTest *ptest = new CTest();

list.AddTail(ptest);

CObject *pOb = list.GetAt(0);

if( pOb->IsKindOf(RUNTIME_CLASS(CTest)) )
{   
    // ist ein CTest-Objekt 
}
 
Mit der Containerklasse sieht das bei mit so aus:
Code:
			pGR2Device = new CGR2Device(); //Dialog Klasse
			pGR2Device->Create(IDD_GR2_DEVICE,this);		
            
			pContainer = new CContainer();
			pContainer->pObject = (CGR2Device*)pGR2Device;
			pContainer->m_device = 1; //GR2

Die abzuspeichernde Classe ist vom CDialog abgeleitet. So müsste das dann auch mit
den Makros DECLARE_DYNAMIC und IMPLEMENT_DYNAMIC funktionieren ?

Code:
class CTest : public CDialog
{
public:
    DECLARE_DYNAMIC(CTest)

    CTest();
    ~CTest();
};
 
Zurück