后期绑定有什么好处?在 C++ 中的函数指针上下文中举一个例子
What are the advantages of late binding? Give one example in context of function pointers in C++
首先,让我澄清一下this问题没有把我的疑问解释清楚。明确上下文。我特别针对 C/C++.
中的函数指针问这个问题
我知道早期绑定和后期绑定的区别及其工作原理。我想了解的是以下一个使用 C/C++ 中的函数指针的示例:
在很多教科书上都提到过:
advantage of late binding is that it is more flexible than early
binding, because decisions about what function to call do not need to
be made until run time.
另外,它提到:
With late binding, the program has to read the address held in the
pointer and then jump to that address. This involves one extra step,
making it slightly slower.
#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;
}
在这里,使用后期绑定没有任何优势,应该首选下面示例中的早期绑定。
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;
有人可以用一个像下面这样的简单示例来解释,其中 后期绑定是有利的,为什么有人应该选择后期绑定而不是早期绑定?
好的,我将跳过整个 "early binding vs late binding" 定义问题并假装你问 "why would someone use function pointers instead of a switch statement?"
因为函数指针更加灵活。它们不是 静态的。 让我们来看看代码的业务端:
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);
}
}
很好,很实用。但它并不灵活。为什么?因为所有可以调用的函数都是由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);
}
现在,如果要添加更多操作,只需将元素插入 funcs
。如果 InvokeOperation
是某个图书馆的一部分,您不一定有权更改它。使用静态绑定,您将拥有一个不灵活的系统;它支持的是它将始终支持的。
使用动态绑定,您可以添加任何您想要的东西,无论您是否有权直接修改库。
首先,让我澄清一下this问题没有把我的疑问解释清楚。明确上下文。我特别针对 C/C++.
中的函数指针问这个问题我知道早期绑定和后期绑定的区别及其工作原理。我想了解的是以下一个使用 C/C++ 中的函数指针的示例:
在很多教科书上都提到过:
advantage of late binding is that it is more flexible than early binding, because decisions about what function to call do not need to be made until run time.
另外,它提到:
With late binding, the program has to read the address held in the pointer and then jump to that address. This involves one extra step, making it slightly slower.
#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;
}
在这里,使用后期绑定没有任何优势,应该首选下面示例中的早期绑定。
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;
有人可以用一个像下面这样的简单示例来解释,其中 后期绑定是有利的,为什么有人应该选择后期绑定而不是早期绑定?
好的,我将跳过整个 "early binding vs late binding" 定义问题并假装你问 "why would someone use function pointers instead of a switch statement?"
因为函数指针更加灵活。它们不是 静态的。 让我们来看看代码的业务端:
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);
}
}
很好,很实用。但它并不灵活。为什么?因为所有可以调用的函数都是由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);
}
现在,如果要添加更多操作,只需将元素插入 funcs
。如果 InvokeOperation
是某个图书馆的一部分,您不一定有权更改它。使用静态绑定,您将拥有一个不灵活的系统;它支持的是它将始终支持的。
使用动态绑定,您可以添加任何您想要的东西,无论您是否有权直接修改库。