Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数指针如何替换switch语句?_C++_C_Pointers_Function Pointers - Fatal编程技术网

C++ 函数指针如何替换switch语句?

C++ 函数指针如何替换switch语句?,c++,c,pointers,function-pointers,C++,C,Pointers,Function Pointers,我正在阅读这篇关于函数指针的教程,它说函数指针可以代替switch语句 . 有人能澄清一下吗 我们有这样一个switch语句: // The four arithmetic operations ... one of these functions is selected // at runtime with a swicth or a function pointer float Plus (float a, float b) { return a+b; } float Minus

我正在阅读这篇关于函数指针的教程,它说函数指针可以代替switch语句 .

有人能澄清一下吗

我们有这样一个switch语句:

// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
float Plus    (float a, float b) { return a+b; }
float Minus   (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide  (float a, float b) { return a/b; }


// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
   float result;

   // execute operation
   switch(opCode)
   {
      case '+' : result = Plus     (a, b); break;
      case '-' : result = Minus    (a, b); break;
      case '*' : result = Multiply (a, b); break;
      case '/' : result = Divide   (a, b); break;
   }

   cout << "Switch: 2+5=" << result << endl;         // display result
}

// Solution with a function pointer - <pt2Func> is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
   float result = pt2Func(a, b);    // call using function pointer

   cout << "Switch replaced by function pointer: 2-5=";  // display result
   cout << result << endl;
}


// Execute example code
void Replace_A_Switch()
{
   cout << endl << "Executing function 'Replace_A_Switch'" << endl;

   Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
   Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}
 void reduce(void *data, size_t nmemb, size_t size,
        void (*op)(void *, void *), void *res){
                int i;
                for (i = 0; i < nmemb; ++i){
                        op(data, res);
                        data = (void *)((unsigned char*)data + size);
                }
        }
总之,函数指针的优点是什么,它总是说函数指针是一种后期绑定机制,但是在本教程中,我没有看到函数指针对于后期绑定的任何优点。
非常感谢您的帮助。谢谢。

您所说的是非常正确的,您仍然需要决定使用什么函数指针

不过,您看到的是一个非常简单、人为的示例,用于解释。它显示了如何利用函数指针。在这种情况下,它可能毫无意义地复杂,但实际案例可能太复杂,无法用于指导这一基本概念

当有很多函数具有相同的开关,或者开关具有相同集合的子集时,差别就会变得更加明显。尽管如此,差别还是一样的(这也很重要)。既然如此,为什么还要重写很多次呢

它还会打开您的代码,以更改决策的方式。也许出于任何原因,您都想将“+”和“-”颠倒过来。更改指针的位置,所有客户机代码都会跟上

最后,如果你甚至不需要做决定呢?例如,如果您只是想做添加版本,而不是更换交换机,该怎么办?显然,加法对于这个级别的设计来说太简单了,但它只是一个例子

无论您使用的是函数指针还是类层次结构,所有这些都是正确的。必须有人决定输入的内容。这些构造的作用是为您提供一种方法,将不同的位组合到正在运行的程序中。它还将负责决定使用哪个版本的东西的部分与这些东西的使用分开。有很多不同的方法来实现这一创造(参见一些创意设计模式)。

正如我所看到的

pt2Func是为引用函数的指针定义的名称

您可以在调用它的主要位置看到它是如何工作的 (删除注释以使其更具可读性)

&plus这是一个指向函数的指针

这是愚蠢的,因为您正在使用指针调用一个函数来引用另一个函数。 没有什么好处,也没有什么特别的作用。。这只是调用减号函数的另一种更复杂的方法


然而,开关函数只是一个普通的开关,封装在一个可重用的函数中

我可以看到如何将“+”、“-”等转换为
枚举
,并将4个func指针存储到按
枚举
顺序排列的数组中。在这之后,
arr[op]
就是您想要的函数,只需执行它即可


另一种选择是
std::map
映射自
+
->
&Plus

,正如本教程所述,它没有任何优点,基本计算器只是一个示例。函数指针的主要用途是允许API开发人员定义函数,该函数执行API创建时未知的操作

一个更好的例子可能是,它采用了比较函数。多亏了这个函数指针参数,才有可能以通用的方式实现排序。由于您不可能知道需要对哪些类型的数据进行排序,因此无法知道必须如何实现
运算符。因此,您希望调用方提供一个实现比较的函数,从而避免这种困境

通常,如果您想以通用方式编程,函数指针通常很有用。它的用途是在其他语言中使用函数参数。例如,如果有人要求您实现一个简单的reduce函数,您可以提出如下建议:

// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
float Plus    (float a, float b) { return a+b; }
float Minus   (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide  (float a, float b) { return a/b; }


// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
   float result;

   // execute operation
   switch(opCode)
   {
      case '+' : result = Plus     (a, b); break;
      case '-' : result = Minus    (a, b); break;
      case '*' : result = Multiply (a, b); break;
      case '/' : result = Divide   (a, b); break;
   }

   cout << "Switch: 2+5=" << result << endl;         // display result
}

// Solution with a function pointer - <pt2Func> is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
   float result = pt2Func(a, b);    // call using function pointer

   cout << "Switch replaced by function pointer: 2-5=";  // display result
   cout << result << endl;
}


// Execute example code
void Replace_A_Switch()
{
   cout << endl << "Executing function 'Replace_A_Switch'" << endl;

   Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
   Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}
 void reduce(void *data, size_t nmemb, size_t size,
        void (*op)(void *, void *), void *res){
                int i;
                for (i = 0; i < nmemb; ++i){
                        op(data, res);
                        data = (void *)((unsigned char*)data + size);
                }
        }
void reduce(void*数据、大小、大小、,
void(*op)(void*,void*),void*res){
int i;
对于(i=0;i

显然,对于乘法、加法和更复杂的运算,用相应的函数替换op来重新编写它是非常有利的。

简而言之,您需要一个函数指针数组,可以根据您的操作码类型进行索引。因为索引是代码> char < /COD>而不是一些合成字节码,这意味着256个元素,并且记住将索引转换成<代码>未签名的char < /C> >,考虑到C++中的编码,为什么不使用一个虚拟的类层次结构,让编译器担心所有的机制?这样也会导致VM速度较慢(相对而言)。。它也与探索这种方法的目的背道而驰。一个虚拟函数不比函数指针快或慢。函数指针就是虚拟函数。谢谢,但是你能给出一个例子或者提供这种例子的任何链接吗?我想C回调是函数指针行后面的真实例子。我想不出有哪家图书馆能使用它们,我会说它很好用。选择一个我想是的cUIAPI。有win32,gtk,motif…等等。