在函数指针赋值中进行转换

tal*_*099 2 c c++

以下函数指针赋值如何:

exit = (void (*)()) &jump;
Run Code Online (Sandbox Code Playgroud)

不同于:

exit = &jump;
Run Code Online (Sandbox Code Playgroud)

其中exit是一个定义为的函数指针:

void (*exit) ();
Run Code Online (Sandbox Code Playgroud)

'jump'是一个声明为的函数:

void jump();
Run Code Online (Sandbox Code Playgroud)

Cin*_*lue 9

exit = (void (*)()) &jump;
Run Code Online (Sandbox Code Playgroud)

第一个使用强制铸造.这很危险,因为它可能搞砸你的程序,而不会让你知道类型是否匹配,因为它不会在编译时被捕获.

所以,如果你这样做:

int func() {return 1;}
auto exit = (void (*)()) &func;
Run Code Online (Sandbox Code Playgroud)

......那会很糟糕.但是,如果您执行以下操作会更好:

exit = &jump;
Run Code Online (Sandbox Code Playgroud)

第二个使用编译时类型检查.这更安全,因为编译器将在编译时检查类型.这为您提供了更强大的类型保证.

最好的选择是使用static_cast<void(*)()>它的类型安全,并告诉程序员你更多的意图是你想要做什么.

auto exit = static_cast<void(*)()>(&func);
Run Code Online (Sandbox Code Playgroud)

如果你有C++,你可以尝试以下方法:

如果您不想关注类型,请使用auto.

auto exit = &func

这将确保类型匹配.如果要检查的类型,使用typeid().name<typeinfo>它存在于C++ 11及更高版本:

std::cout << typeid(exit).name << std::endl;
Run Code Online (Sandbox Code Playgroud)

虽然这通常会为函数提供一些奇怪的输出,但您可能会发现一些可以帮助您的信息,如果两种类型不同,最好的信息就是这些信息.

这是一个工作示例,在运行时使用函数指针转换显示问题: http ://coliru.stacked-crooked.com/a/47f74e8b6f389812