Pain-maker
Mitglied
Hi @ all!
(Das ist zwar ein Thema das schon zur genüge in Foren diskutiert wurde, aber zu meinem konkreten Fall hab ich einfach nichts passendes via Suchmaschinen gefunden...)
Ich bin gerade dabei ein Polymorphe Liste in ISO-C++ zu erstellen und bin nun mit meinem Latein am Ende...
Ich habe es bereits, dank Templates, geschafft eine Liste zu bauen, die Objekte der gleichen Basis-Klasse hält. Wenn ich nun aber versuche eins der Listen-Elemente zu kopieren (klonen) verliert es die Informationen des eigentlichen Typs und fällt auf die Basis-Klasse zurück.
Vielleicht mal zu Beginn der Quellcode:
Ich versuche hier einen neutralen Speicher (DynList<Vehicle> myList) zu schaffen, der die Objekte hält. Die Pointer auf diese Objekte möchte ich dann auf weitere Listen verteilen können.
Mit der Zeile in DynList:: push()...
...funktioniert das auch soweit ganz gut, solange bis versuche eines der Objekte zu kopieren (via new).
Ist ja auch ganz logisch da DynListEntry<_Type> mit _BaseType kompiliert wird. Daher kam ich auf die für mich logischste Lösung: Nämlich:
Dann wird DynListEntry<_Type> mit _DerivedType kompiliert und würde somit den richtigen Typen kennen.
Allerdings erhalte ich dann den Compiler-Error:
Ich bin doch so kurz davor...
Was mache ich noch falsch? Kann mir jemand weiterhelfen?
BTW: Das dem Code noch das Exception-Handling fehlt, weiß ich
Mfg Pain-maker
(Das ist zwar ein Thema das schon zur genüge in Foren diskutiert wurde, aber zu meinem konkreten Fall hab ich einfach nichts passendes via Suchmaschinen gefunden...)
Ich bin gerade dabei ein Polymorphe Liste in ISO-C++ zu erstellen und bin nun mit meinem Latein am Ende...
Ich habe es bereits, dank Templates, geschafft eine Liste zu bauen, die Objekte der gleichen Basis-Klasse hält. Wenn ich nun aber versuche eins der Listen-Elemente zu kopieren (klonen) verliert es die Informationen des eigentlichen Typs und fällt auf die Basis-Klasse zurück.
Vielleicht mal zu Beginn der Quellcode:
PHP:
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <list>
/**
* DynList
*/
template<typename _Type> class DynEntry
{
public:
_Type *data;
public:
// clone
void clone()
{
this->data = new _Type(*data);
}
};
/**
* DynList
*/
template<typename _BaseType> class DynList
{
protected:
typedef typename DynEntry<_BaseType> ListEntry;
std::list<ListEntry> data;
public:
// ~DynList
virtual ~DynList()
{
this->freeMemory();
}
protected:
// freeMemory
void freeMemory()
{
std::list<ListEntry>::iterator iter;
std::list<ListEntry>::iterator iterEnd = this->data.end();
for(iter=this->data.begin(); iter!=iterEnd; iter++)
delete (*iter).data;
}
public:
// push
template<typename _DerivedType> _DerivedType *push(_DerivedType *element)
{
DynEntry<_DerivedType> entryPolymorph;
entryPolymorph.data = new _DerivedType(*element);
ListEntry entry;
entry.data = new _DerivedType(*element);
//this->data.push_back(entry); // Funktioniert, aber der Typ geht beim Klonen verloren
this->data.push_back(entryPolymorph); // Funktioniert nicht --> error C2664: 'void std::list<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'DynEntry<_Type>' to 'DynEntry<_Type> &&'
return dynamic_cast<_DerivedType*>(this->data.back().data);
}
// front
_BaseType *front()
{
return this->data.front();
}
// back
_BaseType *back()
{
return this->data.back();
}
// clone
_BaseType *clone(_BaseType *ptr)
{
std::list<ListEntry>::iterator iter;
std::list<ListEntry>::iterator iterEnd = this->data.end();
for(iter=this->data.begin(); iter!=iterEnd; iter++)
{
if((*iter).data == ptr)
{
this->data.push_back(*iter);
this->data.back().clone(); // Ohne funktioniert, aber dann existiert das gehaltene Objekt nur einmal
return (this->data.back().data);
}
}
return NULL;
}
};
/**
* Vehicle
*/
class Vehicle
{
protected:
char name[32];
public:
Vehicle()
{
strcpy_s(this->name, "Vehicle");
}
virtual ~Vehicle()
{
}
};
/**
* Car
*/
class Car : public Vehicle
{
protected:
int numTires;
public:
Car()
{
strcpy_s(this->name, "Car");
this->numTires = 4;
}
};
/**
* NuclearSubmarine
*/
class NuclearSubmarine : public Vehicle
{
protected:
int numBombs;
public:
NuclearSubmarine()
{
strcpy_s(this->name, "NuclearSubmarine");
this->numBombs = 10;
}
};
/**
* main
*/
void main()
{
DynList<Vehicle> myList; // "Objekt-Speicher"
std::list<Car*> refList; // Liste die Daten aus dem "Objekt-Speicher" hält
// 2 Test-Objekte erzeugen
NuclearSubmarine car1;
Car car2;
// Jeweils eine Kopie auf den "Objekt-Speicher" schieben und den Pointer speichern
NuclearSubmarine *ret1 = myList.push(&car1);
Car *ret2 = myList.push(&car2);
// Objekt kopieren (klonen)
Vehicle *test1 = myList.clone(ret1);
NuclearSubmarine *test2 = (NuclearSubmarine*)test1;
Car *test3 = (Car*)test1;
// Auf eine weitere Liste schieben, welche die Daten (die Pointer auf die eigentlichen Daten) halten soll
refList.push_back((Car*)ret1);
refList.push_back((Car*)ret2);
refList.push_back((Car*)test1);
refList.push_back((Car*)test2);
// Break here!
_getch();
}
Ich versuche hier einen neutralen Speicher (DynList<Vehicle> myList) zu schaffen, der die Objekte hält. Die Pointer auf diese Objekte möchte ich dann auf weitere Listen verteilen können.
Mit der Zeile in DynList:: push()...
PHP:
this->data.push_back(entry)
Ist ja auch ganz logisch da DynListEntry<_Type> mit _BaseType kompiliert wird. Daher kam ich auf die für mich logischste Lösung: Nämlich:
PHP:
this->data.push_back(entryPolymorph);
Allerdings erhalte ich dann den Compiler-Error:
Code:
error C2664: 'void std::list<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'DynEntry<_Type>' to 'DynEntry<_Type> &&'
Ich bin doch so kurz davor...
Was mache ich noch falsch? Kann mir jemand weiterhelfen?
BTW: Das dem Code noch das Exception-Handling fehlt, weiß ich
Mfg Pain-maker
Zuletzt bearbeitet: