Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Problem mit Template + virtual function

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
26.08.2008, 23:46 Uhr
~Beginner2k8
Gast


Hallo Forum,

ich hoffe Ihr könnt mir weiterhelfen. Ich habe folgende Template Klasse...



C++:
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...



C++:
class SortSub : public Sort<float>
{              
  // irgendwelche Variablen
};



...und dann den folgenden Aufruf...



C++:
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!!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
27.08.2008, 08:31 Uhr
stephanw
localhorst


Du holst ja das Objekt "obj" vorher aus einem Array:


C++:
Sort<T>* obj= &SortArray[(Left + Right) >> 1];


Entweder ist dieses Array leer oder der Index geht über die Grenzen hinaus. "obj" zeigt dann irgendwohin, und dann knallt es.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.08.2008, 08:31 Uhr
ao

(Operator)



C++:
static SortSub* SortSubArray;

// Ist hier nix? Kein "SortSubArray = new SortSub[N];" oder so? Dann ist klar, warum es knallt, oder?

Sort<float>::QuickSort(SortSubArray, 0, 4);
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.08.2008, 11:13 Uhr
~Beginner2k8
Gast


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).


C++:
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!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
27.08.2008, 11:33 Uhr
ao

(Operator)


Was genau hast du programmiert? So

C++:
realloc(SortSubArray, 5 * sizeof(SortSub));


oder so?

C++:
SortSubArray = realloc(SortSubArray, 5 * sizeof(SortSub));


Wenn dir der Unterschied nicht klar ist, lies nach, was realloc tut.


Zitat:
Einen Konstruktor habe ich ja nicht ...

Doch. Wenn du keinen eigenen Konstruktor schreibst, hast du immer einen Default-Konstruktor, der von new verwendet wird. Von malloc & Co. allerdings nicht.

Deshalb sollte man in C++ grundsätzlich "new" verwenden und nicht die malloc-Familie. Und für Daten-Arrays gibt es in C++ passende Containerklassen, d.h. man kann auch auf realloc und auf die alten C-Style-Arrays verzichten.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
27.08.2008, 12:58 Uhr
~Beginner2k8
Gast


Ja so hier:


C++:
SortSubArray = realloc(SortSubArray, 5 * sizeof(SortSub));



D.h. die Exception kommt daher, das ich die einzelnen elemente nicht mit new
erzeugt habe? Kann man auf Methoden von Objekten nur zugreifen wenn die
Objekte via "new" erzeugt wurden?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
27.08.2008, 13:47 Uhr
ao

(Operator)


Wenn ich so drüber nachdenke ... bei virtuellen Methoden kann das wohl sein, weil die V-Table vom Konstruktor aufgebaut wird.

Aber wenn du den Code immer nur krümelchenweise zeigst, schwindet die Lust, dir zu helfen, rapide ...

Dein Design finde ich insgesamt seltsam. Ich hab noch nie eine Sortier-Klasse entworfen, aber kann man nicht ein ganz einfaches Klassentemplate machen (ohne static und virtual und diesen ganzen Kram) und gegebenenfalls eine Spezialisierung für den Vergleichsoperator hinzufügen, falls dieser nicht trivial ist?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
27.08.2008, 19:03 Uhr
0xdeadbeef
Gott
(Operator)


Du benutzt ein flaches Array von Unterklassen als Array der Vaterklasse; das geht natürlich schief. Für Polymorphie brauchst du schon Referenzen, bzw., in diesem Fall, ein Zeigerarray. Wobei natürlich die flexiblere Variante wäre, QuickSort zu einer Funktionsvorlage zu machen:

C++:
template <typename T> void QuickSort(T *data) {
  // ...
}


...damit lassen sich dann alle möglichen Arrays sortieren.

Oh, und benutz mit Klassen nie malloc, calloc oder realloc. Keine der drei Funktionen führt Konstruktoren aus, und das geht mindestens mit der vtbl böse daneben. Benutz new.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
27.08.2008, 20:55 Uhr
~Beginner2k8
Gast


Habe jetzt den Array so geändert...


C++:
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

Für besseres Design bin ich natürlich offen, könnt ja eine entsprechende Klasse posten.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
27.08.2008, 21:19 Uhr
0xdeadbeef
Gott
(Operator)


Am einfachsten wäre

C++:
#include <algorithm>


...und std::sort zu benutzen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: