将接受“指针参数”的函数指针转换为另一个接受“引用参数”的函数指针有什么缺点?
考虑以下示例:
#include <iostream>
int test(int* x)
{
(*x)*=2;
return *x;
}
int main()
{
int a = 5;
int b = test(&a);
std::cout<<"a="<<a<<" and b="<<b<<"\r\n";
//Type casting:
int (*test2)(int&) = (int(*)(int&))&test;
int c = 5;
int d = test2(c);
std::cout<<"c="<<c<<" and d="<<d<<"\r\n";
return 0;
}
从动态链接库(DLL)导入函数时特别有用。 例如 Kernel32.dll 中的 WriteFile 函数的语法为:
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
可以转移到:
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
DWORD& NumberOfBytesWritten,
OVERLAPPED& Overlapped
);
虽然引用和指针参数可能(可能)用类似的内部机制实现,但引用不是指针(请参阅:指针变量和引用变量之间有什么区别?),因此,使用一个代替另一个是未定义的行为。
因此,您在所示代码中所做的事情的一个重大缺点是它会产生未定义的行为。
任何像样的编译器都会(或应该)对此发出警告。 Clang-cl(在 Visual Studio 中)给出:
警告:从 'int (*)(int *)' 转换为 'int (*)(int &)' 转换为 不兼容的函数类型 [-Wcast-function-type-strict]
MSVC 给出:
警告 C4191:“类型转换”:从“int (__cdecl *)(int *)' 到 'int (__cdecl *)(int &)'
警告 C4191:使用结果指针进行函数调用可能会导致您的 程序失败