Funktion <=> Instanz
-
shade, bei mir kompiliert der das fehlerlos^^
//edit doch hast wohl recht Oo
-
otze schrieb:
shade, bei mir kompiliert der das fehlerlos^^
//edit doch hast wohl recht Ooum es klarer zu stellen:
folgendes kompiliert nicht:
class A { }; class B { public: B(A a) {} void foo() {} }; int main() { B b(A()); //funktion b.foo(); }
Denn b ist, wie schon gesagt, eine Funktion.
Mein erster code kompiliert natuerlich auch - die Deklaration einer Funktion ist ja vollkommen legal (nur eben nicht das, was wir erwarten)
-
[OT]Oh, Shade, wo du grad mal da bist noch eine Frage.
Hab mir mal den Code zu deinem TicTacToe-Game angeschaut.
Eines verstehe ich nicht.//Methode mit 0 Parametern template<typename Class> class MenuEntryMethod : public MenuEntry { public: typedef void (Class::*Method)(); private: Class* p; Method method; std::string name; protected: void do_action() { (p->*method)(); } std::string do_getName() const { return name; } public: MenuEntryMethod(Class* p, Method method, std::string const& name) : p(p), method(method), name(name) {} };
In der Klasse machst
MenuEntryMethod so etwas:typedef void (Class::*Method)();
Du gibst also dem Typen void den Aliasnamen (Class::*Method)() ???
Und woher kommt der TypMethod method;
dann auf einmal?
Und was machst du hier dann genau:(p->*method)();
?
[/OT]
-
Raptor schrieb:
Du gibst also dem Typen void den Aliasnamen (Class::*Method)() ???
Und woher kommt der Typnein, nicht void
Ich lege einen Typen Method an, der ein Zeiger auf eine Methode ist.
Der Typ ist:
void (Class::)();
das ist ein Zeiger auf eine Methode.
ein zeiger auf eine funktion sieht zB so aus:
void ()();
und dann fuege ich lediglich den namen ein ->
void (*foo)();etwas ungewoehnlich diese syntax, ich weiss. C++ ist syntaktisch gesehen nicht wirklich schoen
schau dir mal www.function-pointer.org an. Dann sollte es dir klar werden. Wenn nicht - frag nochmal
Und was machst du hier dann genau:
(p->*method)();
Ich rufe die Methode mit einem Objekt auf.
Jede Methode braucht ja ein Objet auf das sie angewandt wird.und mit dieser Zeile mache ich nichts anderes als die Methode ueber einen Zeiger mit dem Objekt p aufzurufen.
-
Und was soll der * da?
-
Der * gehört zum binären Operator ->* (nicht lachen, den gibt's wirklich). Links steht ein Zeiger auf ein Objekt, rechts ein Zeiger auf einen Member und der Operator macht in diesem Fall eine aufrufbare Funktion daraus.
-
tag schrieb:
Der * gehört zum binären Operator ->* (nicht lachen, den gibt's wirklich). Links steht ein Zeiger auf ein Objekt, rechts ein Zeiger auf einen Member und der Operator macht in diesem Fall eine aufrufbare Funktion daraus.
Ich dachte immer das wäre ne Combo aus -> und *
. Mit * würde man den Pointer dereferezieren und dann die Funktion dann ganz gewöhnlich mit -> aufrufen.
-
ne, das merkt man zb auch daran, dass der ->* operator nicht überladbar ist
-
otze schrieb:
ne, das merkt man zb auch daran, dass der ->* operator nicht überladbar ist
IMHO ist er aber überladbar!
-
nö man kann ihn net überladen, genauso wie der .* operator
-
-
Jetzt wo ich darüber nachdenke ist es eigentlich auch logisch, dass ->* ein eigener Operator ist. Es gibt Funktion und Funktionspointer aber keine Funktionsvariablen oder Funktionsreferenzen. Was ist der Type von *foo wenn foo eine Funktion ist? foo selbst. Eine Funktion ist aber keine Variable und Funktionsreferenzen gibt es auch nicht.
Wenn nun ->* eine Combo aus -> und * wäre (wie der Syntax ja einläd zu glauben) dann müsste * den Funktionspointer dereferenzieren und dann die Funktion zurückgeben. Geht aber nicht da eine Funktion keine Variable ist und Funktionsreferenzen gibt es auch nicht.
Entweder man macht jetzt aus ->* einen eigenen Operator oder man lässt * einen Pointer zurückgeben den anschließend vom Compiler dereferenziert wird (der kann das Unmögliche wahr machen
) also dereferenziert der * eigentlich gar nichts. Bei:
a->*b
würde also -> aus a ein Klassenpointer machen und * aus b einen Methodenpointer und das ganze wäre glöst.
Nun:
*foo==foo
ergibt aber true wenn foo eine Funktion ist. Da man hier bereits aller Logik widerspricht seh ich eigentlich nicht wieso man für den Fall ->* eine Ausnahme macht und man könnt doch wenigstens konsekent der Logik widersprechen.
-
Dann merkt man es eben daran, dass man nicht A-> *B schreiben kann