Viv*_*yan -1 c c++ function-pointers late-binding
首先,让我澄清这个问题并不能清楚地解释我的怀疑.设置上下文清晰.我在C/C++中专门针对函数指针问这个问题.
我知道早期绑定和后期绑定之间的区别以及它是如何工作的.我想要了解的是以下一个使用C/C++中的函数指针的示例:
在许多教科书中,已经提到:
后期绑定的优点是它比早期绑定更灵活,因为关于调用哪个函数的决定不需要在运行时进行.
另外,它提到:
使用后期绑定,程序必须读取指针中保存的地址,然后跳转到该地址.这涉及一个额外的步骤,使其稍慢.
#include <iostream>
using namespace std;
int Add(int nX, int nY)
{
return nX + nY;
}
int Subtract(int nX, int nY)
{
return nX - nY;
}
int Multiply(int nX, int nY)
{
return nX * nY;
}
int main()
{
int nX;
cout << "Enter a number: ";
cin >> nX;
int nY;
cout << "Enter another number: ";
cin >> nY;
int nOperation;
do
{
cout << "Enter an operation (0=add, 1=subtract, 2=multiply): ";
cin >> nOperation;
} while (nOperation < 0 || nOperation > 2);
// Create a function pointer named pFcn (yes, the syntax is ugly)
int (*pFcn)(int, int);
// Set pFcn to point to the function the user chose
switch (nOperation)
{
case 0: pFcn = Add; break;
case 1: pFcn = Subtract; break;
case 2: pFcn = Multiply; break;
}
// Call the function that pFcn is pointing to with nX and nY as parameters
cout << "The answer is: " << pFcn(nX, nY) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里,没有使用后期绑定和早期绑定的优点,因为下面的例子应该是首选.
int nResult = 0;
switch (nOperation)
{
case 0: nResult = Add(nX, nY); break;
case 1: nResult = Subtract(nX, nY); break;
case 2: nResult = Multiply(nX, nY); break;
}
cout << "The answer is: " << nResult << endl;
Run Code Online (Sandbox Code Playgroud)
有人可以用一个简单的例子来解释一下,后期绑定是有利的,为什么有人会选择它而不是早期绑定?
好的,我将跳过整个"早期绑定与后期绑定"定义问题并假装你问"为什么有人会使用函数指针而不是switch语句?"
因为函数指针更灵活.它们不是静态的.让我们来看看代码的业务结束:
int InvokeOperation(int nOperation, int nX, int nY)
{
switch (nOperation)
{
case 0: return Add(nX, nY);
case 1: return Subtract(nX, nY);
case 2: return Multiply(nX, nY);
}
}
Run Code Online (Sandbox Code Playgroud)
这很好,功能齐全.但它并不灵活.为什么?因为可以调用的所有函数都是由InvokeOperation
; 如果要添加新操作,则必须能够更改InvokeOperation
.
相比之下,如果使用函数指针,则可以构建整个操作注册表:
using Func = int(*)(int, int);
struct Op{Func func; std::string name;};
std::vector<Func> funcs =
{
{&Add, "Add"},
{&Subtract, "Subtract"},
{&Multiply, "Multiply"},
};
int InvokeOperation(int nOperation, int nX, int nY)
{
return funcs[nOperation].func(nX, nY);
}
Run Code Online (Sandbox Code Playgroud)
现在,如果要添加更多操作,只需插入元素即可funcs
.如果InvokeOperation
是某些图书馆的一部分,您不一定有权更改它.使用静态绑定,您将拥有一个不灵活的系统; 它所支持的是它将永远支持的东西.
使用动态绑定,您可以添加所需的任何内容,无论您是否有权直接修改库.