2011-09-06 25 views
7

sự khác biệt giữaReference đến Chức năng cú pháp - có và không có &

typedef void (&FunctionTypeR)(); 

vs

typedef void (FunctionType)(); 

Gì Sản phẩm thứ hai cũng là một tài liệu tham khảo để hoạt động? Có phải FunctionTypeR tương đương với FunctionType& khi được sử dụng làm loại đối số không?

Đối

void foo(FunctionType bar) 

Liệu các runtime tạo một bản sao của thanh tranh luận (một chức năng) khi foo được gọi?

Trả lời

12

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đ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

+0

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)? –

+0

Không, đó là lỗi. – Shahbaz

+0

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'; –

Các vấn đề liên quan