Pointer Datentyp
-
Mal ne dumme Frage:
Nehmen wir mal an, ich muss einen Pointer speichern, der auf zwei unterschiedliche Klassen zeigen kann? Welchen Datentyp nehm ich für den Pointer? Ein WORD?Gruß
-
Wenn die eine Klasse von der anderen Abgeleitet ist, dann nimmst du die Parent Klasse. Wenn beide Klassen von einer anderen Klasse abgeleitet werden, dann nimmst du diese. Im schlimmsten Fall bleibt noch
void* pointer;, das kannst du mit jedem Pointer machen.
-
Hier ein Beispiel für die Benutzung eines Pointers auf die Basisklasse:
#include <iostream> using namespace std; class tier { public: virtual void gibLaut() = 0; }; class katze : public tier { public: void gibLaut() { cout << "miau" << endl; } }; class hund : public tier { public: void gibLaut() { cout << "wau wau" << endl; } }; int main() { hund h; katze k; tier *t;//Pointer auf die Basisklasse tier t = &k;//Katzenadresse zuweisen t->gibLaut(); t = &h;//Hundeadresse zuweisen t->gibLaut(); }
-
Ich kann also nicht sagen, dass der Pointer einfach 16 Bit lang ist (wenn es denn so sein sollte) und er einfach als WORD nicht konvertiert werden soll?
-
OK, ich bin grad fündig geworden und hab festgestellt, dass ein Pointer auf 32-Bit-systemen 4 Byte groß ist. Dann werd ichs mal mit dem void* versuchen.
-
Jetzt hab ich aber doch nochmal eine Frage: Was passiert, wenn ich einen void* habe, der eigentlich auf eine Instanz der Klasse CTier zeigt und in einen void* gecastet wurde, und ich mache jetzt darauf ein delete?
Löscht er mir das Tier?
-
Nein, solange du ihn nicht wieder zurückcastest, dürfte er nur den Speicher für das Objekt selber freigeben (wenn du im CTier dynamischen Speicher verwendest, ist der verloren).
-
Nixblicker schrieb:
Jetzt hab ich aber doch nochmal eine Frage: Was passiert, wenn ich einen void* habe, der eigentlich auf eine Instanz der Klasse CTier zeigt und in einen void* gecastet wurde, und ich mache jetzt darauf ein delete?
Löscht er mir das Tier?delete auf einen void* zeiger ist immer undefiniertes verhalten (auch wenn einige compiler dafür nicht mal ne warnung übrig haben). das zeigerargument muss vom selben typ sein wie der, der von new geliefert wurde (und ein new void geht ja nicht), oder aber ein zeiger auf eine basisklasse des erzeugten objekts, sofern diese klasse einen virtuellen destruktor hat.
-
camper schrieb:
delete auf einen void* zeiger ist immer undefiniertes verhalten (auch wenn einige compiler dafür nicht mal ne warnung übrig haben). [...] (und ein new void geht ja nicht)
Genau dazu wollte ich eigentlich gerade noch nachfragen: new void geht tatsächlich nirgendwo, delete void gibt aber nichtmal beim so hoch gelobten VC++ 8 einen Laut. Kurz bevor ich die Frage abgeschickt hatte, hab ich's mir selbst durch folgendes erklärt:
void *x = new int; delete x;Also der einzige Fall wo nicht zerstört, sondern nur freigegeben wird (alle PODs) - ist das dann analog zu free(void*) oder nach wie vor undefiniert? Rein vom ersten Blick tut es offenbar das was es tun soll.
-
Auch wenn in den Augen von ansi c++ nen delete aufn void * boese ist, die heap(freestore)manager kennen die zeiger und die dazugoehorige anzahl der bytes die reserviert wurden. (new und delete auf PODs iss eh meist auf malloc und free gemappt)
Damit ist das verhalten implementationsabhaengig, kann gut gehen(windows), muss aber nicht.
Zu deutsch: vermeid es einfach !
void * in C++ sollte soweiso mehrmals gründlich hinterfragt werden.
Ciao ...
-
im prinzip ist diese definition ohnehin schwer verständlich. schließlich gibt es nur eine globale überladung für operator new und delete für alle typen ohne klassen-spezifischen operator. und operator delete hat keinen weiteren parameter - dieser operator kann also gar nicht wisssen, auf welchen typ er angewendet wird. so gesehen wird eine delete auf void* vermutlich bei allen typen ohne eigenen operator und mit trivialem destruktor funktionieren - im prinzip :). wer es typsicher brauch, muss halt einen deleter a la shared_ptr mitführen...