Pointer-to-member
-
Hallo liebe Forenmitglieder!
Ich hbe mal eine Frage:
class X{int a,b;}; int X::* p_pointer;ist ja ein Pointer auf einen Member der Klasse X vom Typ int.
Warum aber gibt es das nicht auch für void? also:
void X::* p_pointer;hier streikt der compiler, mit int compiliert alles.
Warum ist das verboten? Wo liegt da das Problem?
-
Seit wann kann man Objekte vom Typ void erzeugen?
-
garnicht, aber ich will halt das gleiche wie void*, nur als pointer-to-member
beispielsweise so:
class Y {int a; float b;} void Y::* ptr; ptr = &Y::a; ... ptr = &Y::b;
-
Dann schreib doch auch
void*und nichtvoid.
-
ein Pointer-to-member ist ja normalerweise der Offset einer Variable in einer Klasse. Wenn ich genau diesen Offset in einer Funktion erhalten will, könnte ich einen Pointer auf einen beliebigen Member eine Klasse gebrauchen, also dasbereits erwähnte
void Y::* ptr;hingegen ist
void* ptr2;ein Pointer auf eine gaz bestimmte Variable. Damit kann ich also den Offset innerhalb der Klasse (zumindest nicht derart einfach) erhalten.
-
Hi hopeful_guest,
mir scheint im Augenblick, dass Du eigentlich von einem Problem der "Überflexibilisierung" stehst.
... und zwar so einem, das man oft mit Polymorphie am Besten begegnet.
Mal andersherum: Wenn du so einen "void-Member-Pointer" in der Hand hättest - was würdest du damit anfangen?
Spätestes beim Zugriff (ega, wie weit du ihn hinausschiebst) musst du wissen, was für ein Ding du in der Hand hast. Diese Information kann man prima den COmpiler verwalten lassen mittels "virtual functions" (Laufzeit) oder templates (Compilezeit).Diese beiden Werkzeuge sind sehr mächtig, weswegen man sich erst einmal sehr gründlich prüfen sollten, ob sie wirklich nicht passen.
... und sollten sie wirklich nicht passen, sollte man sich überlegen, ob man nicht vielleicht mit einer anderen Sprache besser bedient wäre.Gruß,
Simon2.
-
Hi hopeful_guest,
ich vermute mal du hälst es für einen normalen Pointer,
aber es ist ein Pointer auf eine member variable.Hier vielleicht ein kurzer Code-Ausschnitt, der dir den
Unterschied verdeutlicht:#include <iostream> class A{ public: int a; int b; A(int a, int b) : a(a), b(b){ } }; int main(){ A a1(1, 2); A a2(3, 4); int A::* p1 = &A::a; int A::* p2 = &A::b; std::cout << a1.*p1 << std::endl; std::cout << a1.*p2 << std::endl; std::cout << a2.*p1 << std::endl; std::cout << a2.*p2 << std::endl; return 0; }Ausgabe:
1
2
3
4Du sagst quasi, welche member-Variable er verwenden soll, wenn du den
Pointer auf einem Objekt verwendest.Ich hoffe das hilft dir weiter.
Gruß,
CSpille
-
neinnein, ich weiß schon, dass das ein pointer auf einen Member ist. Genau das will ich auch, weil wiegesagt der dann eben genau gleich dem Offset in Bytes der Variable in die Strukur hinein ist.
Ich habe schon eine Notlösung gefunden, mit polymorphie oder templates geht es leider auchnicht, weil ich die Funktion in einer templateklasse verwende, um eben den Offset einer Variable in der, als Template übergebenen Klasse zu berechnen.
Aber das ist auch alles egal.
Mich würde es lediglich interessieren, warum es denn keine solchen void Pointer-to-member gibt, in Analogie zum "normalen" void pointer, welcher ja "legal" ist.
-
Suchst du vielleicht
offsetof? Das Makro funktioniert aber nur bei POD-Typen zuverlässig, verwende es nicht bei anderen Klassen!Was willst du überhaupt erreichen? Ich habe bisher in C++ noch nie Pointer-to-Member (ausser auf Funktionen) benötigt und habe sie auch nie vermisst...
-
hopeful_guest schrieb:
...Genau das will ich auch, weil wiegesagt der dann eben genau gleich dem Offset in Bytes der Variable in die Strukur hinein ist...
Einerseits ist mir immer noch total schleierhaft, wofür man den "Offset in Bytes einer Variable" haben möchte (außer für Spielereien oder den Versuch, "Reflection" in C++ zu pfopfen).
Andererseits bin ich mir gar nicht sicher, dass Member-pointer das auch garantiert liefern. Letztlich muss nur gewärleistet sein, dass über so einen Member-Pointer ein Zugriff auf das jeweilige Member möglich ist - dass das direkt über einen "Byte-offset" geschieht, ist nicht zwingend notwendig.BTW: Hast du dir schon berlegt, wie das mit Vererbungshierachien (ggf. Mehrfachvererbung) etc. laufen soll?
Gruß,
Simon2.
-
Wenn ihr unbedingt wissen wollt, geht es darum, in folgender Struktur, den richtign Offset zu hinterlegen:
http://msdn.microsoft.com/en-us/library/bb172630(v=VS.85).aspx
Ich will dass der berechnet und nicht manuell als Kostante angegeben wird, um Fehler zu vermeiden. Das mit offsetof muss ich mir einmal anschauen, das kannte ich bisher nicht, danke für den Tipp, evtl. funktionierts damit sauber!
-
ok, mit offsetof und templates sollte es schön funktionieren.Herzlichen Dank, für den Tipp, Nexus! Jedoch bleibt die Anfanges-Frage bestehen, warum denn
void* SampleClass::* ptrverboten ist?