Problem mit Template + virtual function
-
Hallo Forum,
ich hoffe Ihr könnt mir weiterhelfen. Ich habe folgende Template Klasse...
template <class T> class Sort { static Sort<T>* SortArray; static void QuickSort(int Left, int Right); public: virtual T* GetSortingValue(); static void QuickSort(Sort<T>* Array, int Left, int Right); }; template <class T> Sort<T>* Sort<T>::SortArray= NULL; template <class T> T* Sort<T>::GetSortingValue() { static T dummy; return &dummy; } template <class T> void Sort<T>::QuickSort(Sort<T>* Array, int Left, int Right) { SortArray= Array; QuickSort(Left, Right); } template <class T> void Sort<T>::QuickSort(int Left, int Right) { Sort<T>* obj= &SortArray[(Left + Right) >> 1]; T* Piv= obj->GetSortingValue(); //... }...und folgende Klasse die davon erbt...
class SortSub : public Sort<float> { // irgendwelche Variablen };...und dann den folgenden Aufruf...
static SortSub* SortSubArray; Sort<float>::QuickSort(SortSubArray, 0, 4);Leider knallt es immer an der Stelle...
T Piv= obj->GetSortingValue();*
...mit dieser Fehlermeldung (unhandled exception, access writing violation...)
Irgendwie kann er die virtuelle Methode nicht aufrufen,
aber ich weiß nicht was da los ist. Bitte helft mir! Danke!!
-
wird SortSubArray auch irgendwo geeignet initialisiert?
-
Hallo!
Ich habe mir vor dem Thread hier im Debugger den obj pointer ausgeben lassen
und er zeigte auf Daten. Allerdings bin ich durch Euren Hinweis darauf gekommen das
der SortSubArray ja nur mit realloc() erzeugt wird (kann dynamisch wachsen).realloc(SortSubArray, 5 * sizeof(SortSub));D.h. die einzelnen SortSub Elemente des Arrays werden nicht über new erzeugt.
Kann das irgendwie daran liegen? Das ich nur den Platz für die Objekte erzeuge
aber eben nicht über "new"? Und wenn ja warum genau nochmal ist das so?
Einen Konstruktor habe ich ja eigentlich nicht der durch new aufgerufen werden müßte.Vielen Dank!
-
Hallo,
Beginner2k8 schrieb:
Allerdings bin ich durch Euren Hinweis darauf gekommen das
der SortSubArray ja nur mit realloc() erzeugt wird (kann dynamisch wachsen).Nur realloc? Dann ist zu beachten, dass jeder realloc übergebene Zeiger entweder NULL (verhält sich dann wie malloc) oder ein von einem vorherigen Aufruf der Speicherreservierungs-Funktionen erhaltener Zeiger sein muss.
MfG,
Probe-Nutzer
-
Beginner2k8 schrieb:
Hallo!
Ich habe mir vor dem Thread hier im Debugger den obj pointer ausgeben lassen
und er zeigte auf Daten. Allerdings bin ich durch Euren Hinweis darauf gekommen das
der SortSubArray ja nur mit realloc() erzeugt wird (kann dynamisch wachsen).realloc(SortSubArray, 5 * sizeof(SortSub));D.h. die einzelnen SortSub Elemente des Arrays werden nicht über new erzeugt.
vergiss realloc. realloc=evil zumal ich noch nie überzeugend demonstriert bekommen habe, dass die Fähigkeit, einen Speicherblock direkt vergrößern zu können, in hinreichend komplexen Programmen signifikant oft genutzt werden kann.
Kann das irgendwie daran liegen? Das ich nur den Platz für die Objekte erzeuge
aber eben nicht über "new"? Und wenn ja warum genau nochmal ist das so?
Einen Konstruktor habe ich ja eigentlich nicht der durch new aufgerufen werden müßte.Irgendwie, schon. Weil Sort<T> kein POD ist. Sort<T> besitzt tatsächlich sogar zwei Konstruktoren, und einen davon muss du zur Erzeugung benutzen.
Wenn du schon anfängst, mit Templates herumzuspielen, sollte doch nichts gegen vector & co sprechen.
-
Kleine Korrektur, so mache ich es:
SortSubArray = realloc(SortSubArray, 5 * sizeof(SortSub));D.h. die Exception kommt daher, das ich die einzelnen elemente nicht mit new
erzeugt habe... okay dann werde ich das mal ändern. Danke!
-
malloc und Konsorte mischt man besser nicht mit new und Konsorte.
Simon
-
simon.gysi schrieb:
malloc und Konsorte mischt man besser nicht mit new und Konsorte.
SimonEr hats auch nicht gemischt (steht da zumindest nicht), aber er hat die Ctoren dür die Arrayelemente nicht aufgerufen.
malloc & Co sollte man in C++ generell garnicht nutzen, eben aus diesem Grund. Seltene Ausnahmen (z.B. implementieren eines eigenen operator new) bestätigen wie immer die Regel.
-
Habe jetzt den Array so geändert...
static SortSub** SortSubArray;...und jedes Element (welche nun Pointer sind) mit new erzeugt.
Jetzt funktioniert alles!

Jetzt kann ich mit dem Template Parameter einstellen, von welchem
Typ die zu vergleichende Variable eines sortierbaren (d.h. von
class Sort abgeleiteten) Objekts ist
-
Beginner2k8 schrieb:
static SortSub** SortSubArray;Ich habe jetzt nicht den ganzen Thread verfolgt, aber das graust mich schon zu sehen. Bist du sicher, dass das nötig ist? Oder doch besser mit std::vector arbeiten?