Różnica polega na tym, że nie mogą tworzyć obiekty typu funkcji, ale można tworzyć obiektów funkcji wskaźnik rodzaj i funkcję odniesienia typu.
Oznacza to, że jeśli masz funkcję, powiedzmy f()
jak:
void f(){}
to tutaj jest to, co można zrobić, a czego nie może zrobić: kod
FunctionType fun1 = f; //error - cannot create object of function type
FunctionType *fun2 = f; //ok
FunctionTypeR fun3 = f; //ok
test:
typedef void (&FunctionTypeR)();
typedef void FunctionType();
void f(){}
int main() {
FunctionType fun1 = f; //error - cannot create object of function type
FunctionType *fun2 = f; //ok
FunctionTypeR fun3 = f; //ok
return 0;
}
Zobacz teraz błąd kompilacji (i ostrzeżenia):
prog.cpp: In function ‘int main()’:
prog.cpp:7: error: function ‘void fun1()’ is initialized like a variable
prog.cpp:8: warning: unused variable ‘fun2’
prog.cpp:9: warning: unused variable ‘fun3’
demo online: http://ideone.com/hpTEv
Jednak jeśli używasz FunctionType
(która jest rodzajem funkcji) w liście parametrów funkcji jak:
void foo(FunctionType bar);
to jest to równoznaczne z
void foo(FunctionType * bar);
Oznacza to, że O znaczenia, co piszesz, można wywołać funkcję używając bar
jak:
bar(); //ok
(*bar)(); //ok
Oznacza to, że można napisać tak:
void h(FunctionType fun) { fun(); }
void g(FunctionType fun) { (*fun)(); }
Demo: http://ideone.com/kwUE9
Wynika to funkcji typ do regulacji wskaźnika typu regulacja; czyli rodzaj funkcja jest regulować stać się wskaźnik funkcjonować typ:
Function type | Function pointer type (adjusted type)
void() | void (*)()
void (int) | void (*)(int)
int (int,int) | int (*)(int,int)
.... | ... so on
C++ 03 Standardowe mówi w §13.1/3, zgłoszeń
parametrów, które różnią się tylko tym, że jeden jest funkcją typu i drugi wskaźnik tego samego typu reakcji są równoważną. To znaczy, że typ funkcji jest dostosowywany, aby stać się wskaźnikiem dla typu funkcji (8.3.5).
[Example:
void h(int());
void h(int (*)()); // redeclaration of h(int())
void h(int x()) { } // definition of h(int())
void h(int (*x)()) { } // ill-formed: redefinition of h(int())
]
A jeśli używasz `FunctionTypeR
(która jest funkcją odniesienia typ) jako:
void foo(FunctionTypeR bar);
to jest to równoznaczne z:
void foo(FunctionType * & bar);
, a
void h(FunctionTypeR fun) { fun(); }
void g(FunctionTypeR fun) { (*fun)(); }
Demo: http://ideone.com/SmtQv
interesująca część ...
Można użyć FunctionType do zadeklarować funkcji (ale nie go zdefiniować).
Na przykład
struct A
{
//member function declaration.
FunctionType f; //equivalent to : void f();
};
void A::f() //definition
{
std::cout << "haha" << std::endl;
}
//forward declaration
FunctionType h; //equivalent to : void h();
int main() {
A a;
a.f(); //call member function
h(); //call non-member function
}
void h() //definition goes below main()
{
std::cout <<"hmmm.." << std::endl;
}
Demo: http://ideone.com/W4ED2
Czy to znaczy void foo (bar FunctionType) jest rzeczywiście foo (FunctionType & bar)? która jest odpowiednikiem foo (FunctionTypeR bar)? –
Nie, to błąd. – Shahbaz
void 'foo (FunctionType bar)' nie jest błędem. kompiluje i działa. Błąd to "FunctionType fun1 = f"; –