Funkionsreferenzen statt Funktionszeigern?
-
wollte mal fragen ob man statt funktionszeigern auch funktionsreferenzen nutzen kann. also z.B:
void foo(int (&f)(int)); //statt void foo(int (*f)(int));
also ich habs in einem beispiel probiert und es geht, allerdings halt mit dem VC++Express-Compiler, daher weiß ich nicht genau ob das auch woanders funktioniert, also unter dem Standard.
Hintergrund der Frage ist, dass ich mir ersparen möchte den Funktionszeiger auf Null testen zu müssen, was ja möglich sein könnte, habs mal ausprobiert und das programm stürzt dann natürlich ab.
danke schon mal im voraus.
grüße
-
Ist Standard.
greetz, Swordfish
-
ja, aber beachte, dass du keine referenzen auf memberfunktionen haben kannst.
-
warum kann ich keine referenzen auf memberfunktionen haben?
-
class foo_t { public: void bar( ) { } }; int main( ) { void ( foo_t::*static_member_ref )( void ) = &foo_t::bar; foo_t a; ( a.*static_member_ref )( ); }
Ich schätze, weil man Referenzen nicht (explizit) dereferenzieren kann.
greetz, Swordfish
PS: Eine Referenz auf statische Methoden ist möglich.
-
das beispiel versteh ich nicht ganz
class foo_t { public: void bar( ) { } }; int main( ) { // was ist denn *static_member_ref void ( foo_t::*static_member_ref )( void ) = &foo_t::bar; foo_t a; // a hat doch nur bar() als member funktio oder nicht? ( a.*static_member_ref )( ); }
-
FreakyBKA schrieb:
das beispiel versteh ich nicht ganz
... // was ist denn *static_member_ref void ( foo_t::*static_member_ref )( void ) = &foo_t::bar; ...
Ist ein ganz normale Variablendeklaration.
so wie in:int i; // Variable vom Typ int void (*i)(int); // ... vom Typ "Funktion, mit int als Parameter und void Rückgabe" void (C::*i)(int); // ... vom Typ "Memberfunktion der Klasse C, mit int als Parameter und void Rückgabe" void (C::*static_member_ref)(void); // ... vom Typ "Memberfunktion der Klasse C, ohne Parameter und void Rückgabe"
Trotzdem stimme ich Dir zu: Ich verstehe nicht, was das mit "Referenz auf eine Memberfunktion" zu tun hat.
Gruß,
Simon2.
-
Simon2 schrieb:
Trotzdem stimme ich Dir zu: Ich verstehe nicht, was das mit "Referenz auf eine Memberfunktion" zu tun hat.
Ich schätze Swordfish wollte auf den Aufruf dieser "Memberfunktionsreferenz" hinaus. Die Operatoren dafür sind .* und ->*, beide implizieren eine Dereferenzierung, und die funktioniert nunmal nur bei Zeigern, nicht bei Referenzen.
-
Simon2 schrieb:
FreakyBKA schrieb:
das beispiel versteh ich nicht ganz
... // was ist denn *static_member_ref void ( foo_t::*static_member_ref )( void ) = &foo_t::bar; ...
Ist ein ganz normale Variablendeklaration.
wieso kann ich denn außerhalb der klasse neue member deklarieren? das hab ich noch nirgendwo gesehen.
-
naja das ginge dann wie beim normalen "dereferenzeieren" von referenzen durch Weglassen des *-operators:
typedef int (C::mem_fun_ptr*)(int); typedef int (C::mem_fun_ref&)(int); class C { public: int foo(int); }; int main() { mem_fun_ptr mfp = &C::foo; mem_fun_ref mfr = C::foo; C c; int i = c.*mfp(14); int j = c.mfr(15); }
also ganz analog zu normalen Zeigern/referenzen - aber geht wohl nicht
-
pumuckl schrieb:
also ganz analog zu normalen Zeigern/referenzen - aber geht wohl nicht
Würde mir als Compiler schwerfallen das von einem Methodenaufruf (mfr ist eine Memberfunktion) oder Funktionszeigeraufruf (mfr ist ein public Member vom Typ Funktionszeiger) zu unterscheiden
Wäre wohl technisch zu aufwendig gewesen.
-
FreakyBKA schrieb:
...
... // was ist denn *static_member_ref void ( foo_t::*static_member_ref )( void ) = &foo_t::bar; ...
Ist ein ganz normale Variablendeklaration.
wieso kann ich denn außerhalb der klasse neue member deklarieren? ...
Tust Du auch gar nicht und das habe ich auch nicht behauptet.
Nochmal zum genau lesen: Es ist eine Deklaration einer Variablen eines Typs.In diesem Beispiel: Du hast eine Variable namens "static_member_ref" (könnte auch "Hugo" heißen) und diese hat den Typ "Zeiger auf void-void-Memberfunktion der Klasse foot_t".
Die spannenden Frage ist doch: Was kann man mit einer solchen Variable anfangen ?Antwort: Alles, was man auch sonst mit einem (Funktions)-Zeiger machen kann: Auf verschiedene "Ziele" zeigen und per Dereferenzierung auf diese "Ziele" zugreifen.
Natürlich wird (wie bei jedem Zeiger) bei "... auf zeigen lassen.." (= Adresse zuweisen) geprüft, ob der Typ stimmt; sonst meckert der Compiler.
struct C { void a(); void b(); int c(); void c(int); }; struct D { void a(); }; int i1, i2; double d; int main() { C c; void (C::*mem_fun_ptr)(void); // Zeiger-variable... analog zu: int* i_ptr; mem_fun_ptr = &C::a; // OK, Typ passt ... analog zu: i_ptr = &i1; (c.*mem_fun_ptr)(); // ruft c.a() auf ... analog zu: *i_ptr = 1; // ... i1 wird gesetzt mem_fun_ptr = &C::b; // OK, Typ passt ... analog zu: i_ptr = &i2; (c.*mem_fun_ptr)(); // ruft c.b() auf ... analog zu: *i_ptr = 2; // ... i2 wird gesetzt mem_fun_ptr = &C::c; // ERROR: Typ passt nicht ... mem_fun_ptr = &D::a; // ERROR: Typ passt nicht ... analog zu: i_ptr = &d; ...
Gruß,
Simon2.
-
LordJaxom schrieb:
Simon2 schrieb:
Trotzdem stimme ich Dir zu: Ich verstehe nicht, was das mit "Referenz auf eine Memberfunktion" zu tun hat.
Ich schätze Swordfish wollte auf den Aufruf dieser "Memberfunktionsreferenz" hinaus. Die Operatoren dafür sind .* und ->*, beide implizieren eine Dereferenzierung, und die funktioniert nunmal nur bei Zeigern, nicht bei Referenzen.
Cool, es gibt Leute, die mich verstehen
Mich würd' aber interessieren, ob es noch einen anderen Grund gibt, warum es keine "Methodenreferenzen" geben kann. Von einem ungültigem
::&
konstrukt einmal abgesehen.greetz, Swordfish