Tôi có một vấn đề với sự hiểu biết một số C++ cú pháp kết hợp với chức năng gợi ý và tờ khai chức năng, đó là:Giải thích về con trỏ hàm
Thông thường khi chúng ta muốn khai báo một loại chức năng chúng ta làm một cái gì đó như:
typedef void(*functionPtr)(int);
và điều này là tốt cho tôi. Từ bây giờ trên hàm functionPtr là một kiểu, biểu thị con trỏ cho hàm , hàm này trả về void và lấy int bằng một giá trị làm đối số.
Chúng ta có thể sử dụng nó như sau:
typedef void(*functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
Và chúng tôi nhận 5
in trên một màn hình.
chúng tôi đã có con trỏ đến hàm fun
, chúng tôi chỉ định một số con trỏ hiện có để hoạt động - function
và chúng tôi thực thi hàm này bằng con trỏ. Mát mẻ.
Bây giờ khi đọc trong một số sách, chức năng và con trỏ đến hàm được xử lý bằng cách nào đó giống nhau, vì vậy trên thực tế sau khi khai báo hàm function()
mỗi khi chúng ta nói hàm, nghĩa là hàm thực và con trỏ hoạt động cùng loại, biên dịch và mọi hướng dẫn cho kết quả tương tự (5 in trên một màn hình):
int main() {
functionPtr fun = function;
fun(5);
(*fun)(5);
(*function)(5);
function(5);
return 0;
}
Bây giờ miễn là tôi có thể tưởng tượng, rằng con trỏ đến chức năng và chức năng là khá nhiều như nhau, thì đó là bằng cách nào đó tốt cho tôi .
Sau đó, tôi mặc dù, nếu con trỏ đến hoạt động và chức năng thực sự là như vậy, thì tại sao tôi không thể làm như sau:
typedef void(functionPtr)(int); //removed *
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
này mang lại cho tôi lỗi sau:
prog.cpp:12:14: warning: declaration of 'void fun(int)' has 'extern' and is initialized functionPtr fun = function;
do đó tôi hiểu, vì một số lý do trình biên dịch giờ đây đã hiểu, niềm vui đó là đã tồn tại chức năng. Sau đó, tôi đã thử theo dõi:
int main() {
functionPtr fun;
fun(5);
return 0;
}
Và tôi gặp lỗi liên kết. Tôi bằng cách nào đó hiểu, rằng như trình biên dịch bây giờ xử lý niềm vui như chức năng đã tồn tại, sau đó do thực tế, niềm vui đó là hư không được xác định, tôi sẽ nhận được lỗi liên kết. Vì vậy, tôi đã thay đổi tên của biến:
typedef void(functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr function;
function(5);
return 0;
}
Bây giờ chức năng trong bóng tối chính chức năng tên toàn cầu, vì vậy function(5)
được sử dụng từ khai functionPtr function;
Nó hoạt động tốt và in 5 trên màn hình.
Vì vậy, bây giờ tôi bị sốc. Tại sao điều này xảy ra?Ngoài ra điều sai lầm được, rằng khi con trỏ hàm được khai báo như thế này:
typedef void(*functionPtr)(int);
tôi có thể tạo ra chức năng của loại functionPtr ở sau cách:
functionPtr function(int a){
std::cout << a << std::endl;
}
trong khi, khi tuyên bố cái gì đó như:
typedef void(functionPtr)(int);
làm điều này:
functionPtr function(int a){
std::cout << a << std::endl;
}
được biên dịch bởi một trình biên dịch như hàm trả về hàm. Nếu điều này là như vậy, tại sao khai báo trước đó (typedef void(functionPtr)(int);
) biết rằng đây là một hàm trả về void và không trả về hàm functionPtr?
Có thể ai đó vui lòng giải thích điều gì thực sự đang xảy ra thiếu sót đối với tôi không?
Tôi đang sử dụng trình biên dịch g ++ C++ với tùy chọn C++ 14 được bật.
đoạn mã này chưa được biên soạn. Các đoạn mã, đó là: 'functionPtr vui vẻ; fun (5); '(không gán) Ở đây vui được xem như một số hàm, ở đâu đó tồn tại, nhưng liên kết không thể nhìn thấy nó, vì vậy tôi gặp lỗi liên kết – DawidPi
Vì vậy, tại sao khi' typedef void (functionPtr) (int); 'là như thế này và tôi có: functionPtr vui vẻ; vui vẻ(); Tôi gặp lỗi liên kết? Xem ở đây: https://ideone.com/e20FmU – DawidPi
@DawidPi Bởi vì, như SergeyA cũng giải thích, mã đó là không chính xác. Chỉ có thể làm việc trong trường hợp được đăng trong câu trả lời này, nơi chức năng 'hàm' được triển khai. Trong trường hợp của bạn vui vẻ là không. – LPs