2015-12-13 15 views
6

tôi đã xác định một số chức năng và tôi in địa chỉ của họ như thế này:C++ con trỏ đến chức năng không thay đổi

#include<iostream> 
#include <string> 

using std::cout; 

std::string func() 
{ 
    return "hello world\n"; 

} 

int func2(int n) 
{ 
    if (n==0) 
    { 
     cout << func2 << std::endl; 
     return 1; 
    } 

    cout << func2 << std::endl; 

    return n + func2(n - 1); 
} 

//================================================ 
int main() 
{ 
    int (*fun)(int) = func2; 

    cout << fun; 

    cout << std::endl << func2(3); 
} 

Khi tôi in tên của function (địa chỉ) tất cả đều in 1 trên trình biên dịch của tôi (MinGW gcc 4.8) .

Có OK hay không?

Trả lời

0

Bạn' không in lại địa chỉ vì nó được chuyển thành giá trị boolean.

Nhưng bạn có thể làm ví dụ: này:

std::cout << reinterpret_cast<unsigned long long int *>(func2) << std::endl; 

Bây giờ bạn sẽ nhận được địa chỉ thực.

+0

Giả sử rằng kích thước của một con trỏ hàm không lớn hơn kích thước của 'unsigned long long int'. Bạn cũng nên thêm 'const' vào dàn diễn viên để ngăn ngừa tai nạn. –

+1

Vâng, vâng ... trong C++ 11 dài lâu dài ít nhất 64 bit. – juzzlin

+0

Vì vậy? Điều gì xảy ra nếu con trỏ là 128 bit trong tương lai? Một khi họ chỉ có 16 bit. –

3

Nó không tồn tại quá tải operator<< cho std::ostream có con trỏ hàm. Do đó, quá tải operator<<(std::ostream&, bool) được ưu tiên. Địa chỉ của hàm luôn được đánh giá là true khi được chuyển đổi thành bool. Do đó, 1 được in.

Alternatevely, nếu một con trỏ hàm là không lớn hơn so với kích thước của một con trỏ dữ liệu, bạn có thể cast con trỏ hàm của bạn đến một void* qua reinterpret_cast và gợi lên sự quá tải operator<<(std::ostream&, void*) và do đó có được địa chỉ thực của hàm in ra.

int (*fun)(int) = func2; 
std::cout << reinterpret_cast<void*>(fun) << std::endl; 

Live Demo

Tuy nhiên, như một cách chính xác Neil và M.M đề cập trong các ý kiến ​​không có chuyển đổi tiêu chuẩn từ một con trỏ hàm để một con trỏ dữ liệu, và điều này có thể gợi lên hành vi không xác định.

Ngoài ra, và theo ý kiến ​​khiêm tốn của tôi đúng cách, bạn có thể định dạng con trỏ chức năng của bạn như là một mảng đệm char và chuyển đổi địa chỉ của mình cho một chuỗi theo cách sau:

unsigned char *p = reinterpret_cast<unsigned char*>(&func2); 
std::stringstream ss; 
ss << std::hex << std::setfill('0'); 
for(int i(sizeof(func2) - 1); i >= 0; --i) ss << std::setw(2) 
               << static_cast<unsigned int>(p[i]); 
std::cout << ss.str() << std::endl; 

Live Demo

+1

Giả sử rằng kích thước của một con trỏ hàm không lớn hơn kích thước của một con trỏ dữ liệu. Bạn cũng nên thêm 'const' vào dàn diễn viên để ngăn ngừa tai nạn. –

+0

@NeilKirk Đúng vậy. – 101010

+0

lưu ý: chuyển đổi này thành 'void *' không bắt buộc phải tồn tại –

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