Sự khác biệt là bạn không có thể tạo các đối tượng của loại hình chức năng, nhưng bạn có thể tạo các đối tượng của chức năng con trỏ loại, và chức năng tham khảo loại.
Điều đó có nghĩa nếu bạn đã là một chức năng, nói f()
như:
void f(){}
thì đây là những gì bạn có thể làm, và những gì bạn không thể làm: Mã
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;
}
Bây giờ, hãy xem lỗi biên dịch (và cảnh báo):
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’
bản demo online: http://ideone.com/hpTEv
Tuy nhiên, nếu bạn sử dụng FunctionType
(mà là một loại chức năng) trong một danh sách tham số chức năng như:
void foo(FunctionType bar);
sau đó nó tương đương với
void foo(FunctionType * bar);
Điều đó có nghĩa là, n o có vấn đề gì bạn viết, bạn có thể gọi hàm sử dụng bar
như:
bar(); //ok
(*bar)(); //ok
Đó là, bạn có thể viết này:
void h(FunctionType fun) { fun(); }
void g(FunctionType fun) { (*fun)(); }
Demo: http://ideone.com/kwUE9
Điều này là do chức năng loại chức năng kiểu con trỏ điều chỉnh; đó là, chức năng loại là điều chỉnh để trở thành một con trỏ thực hiện chức năng loại:
Function type | Function pointer type (adjusted type)
void() | void (*)()
void (int) | void (*)(int)
int (int,int) | int (*)(int,int)
.... | ... so on
Tiêu chuẩn C++ 03 nói trong §13.1/3, tờ khai
Parameter mà chỉ khác nhau ở một trong đó là một loại chức năng và người kia là một con trỏ đến kiểu chức năng tương tự là tương đương. Tức là, loại chức năng được điều chỉnh để trở thành con trỏ thành kiểu hàm (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())
]
Và nếu bạn sử dụng `FunctionTypeR
(mà là một chức năng tham khảo type) như:
void foo(FunctionTypeR bar);
sau đó nó tương đương với:
void foo(FunctionType * & bar);
Và,
void h(FunctionTypeR fun) { fun(); }
void g(FunctionTypeR fun) { (*fun)(); }
Demo: phần http://ideone.com/SmtQv
Thú vị ...
Bạn có thể sử dụng FunctionType để tuyên bố một chức năng (nhưng không phải để xác định nó).
Ví dụ,
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
Liệu nó có nghĩa void foo (bar FunctionType) thực sự là foo (FunctionType & bar)? tương đương với foo (thanh FunctionTypeR)? –
Không, đó là lỗi. – Shahbaz
void 'foo (thanh FunctionType)' không phải là lỗi. nó biên dịch và chạy. Lỗi là 'FunctionType fun1 = f'; –